/**
 * Dialog components for modals, confirmations, and input dialogs.
 */

import React, { useRef, useState } from 'react';
import { Box, Text, useInput, measureElement } from 'ink';
import TextInput from './TextInput.js';
import { colors } from '../theme.js';

/**
 * Base dialog wrapper props.
 */
interface DialogWrapperProps {
  /** Dialog title */
  title: string;
  /** Border color */
  borderColor?: string;
  /** Dialog content */
  children: React.ReactNode;
  /** Dialog width */
  width?: number;
  /** Dialog Background Color */
  backgroundColor?: string;
}


export function DialogWrapper({
  title,
  borderColor = colors.primary,
  children,
  width = 60,
  backgroundColor = colors.bg,
}: DialogWrapperProps): React.ReactElement {
  const ref = useRef<any>(null);
  const [height, setHeight] = useState<number | null>(null);

  // measure after render
  React.useLayoutEffect(() => {
    if (ref.current) {
      const { height } = measureElement(ref.current);
      setHeight(height);
    }
  }, [children, title, width]);

  return (
    <Box flexDirection="column">

      {/* Opaque backing layer */}
      {height !== null && (
        <Box
          position="absolute"
          flexDirection="column"
          width={width}
          height={height}
          backgroundColor={backgroundColor}
        >
          {Array.from({ length: height }).map((_, i) => (
            <Text key={i} backgroundColor={backgroundColor}>
              {' '.repeat(width)}
            </Text>
          ))}
        </Box>
      )}

      {/* Actual dialog */}
      <Box
        ref={ref}
        flexDirection="column"
        borderStyle="double"
        borderColor={borderColor}
        paddingX={2}
        paddingY={1}
        width={width}
        backgroundColor={backgroundColor}
      >
        <Text color={borderColor} bold>
          {title}
        </Text>

        <Box marginY={1} flexDirection="column">
          {children}
        </Box>
      </Box>

    </Box>
  );
}

/**
 * Props for InputDialog component.
 */
interface InputDialogProps {
  /** Dialog title */
  title: string;
  /** Input prompt/label */
  prompt: string;
  /** Initial value */
  initialValue?: string;
  /** Placeholder text */
  placeholder?: string;
  /** Submit handler */
  onSubmit: (value: string) => void;
  /** Cancel handler */
  onCancel: () => void;
  /** Whether dialog is visible/active */
  isActive?: boolean;
}

/**
 * Input dialog for getting text input from user.
 */
export function InputDialog({
  title,
  prompt,
  initialValue = '',
  placeholder,
  onSubmit,
  onCancel,
  isActive = true,
}: InputDialogProps): React.ReactElement {
  const [value, setValue] = useState(initialValue);

  useInput((input, key) => {
    if (!isActive) return;
    
    if (key.escape) {
      onCancel();
    }
  }, { isActive });

  const handleSubmit = (val: string) => {
    onSubmit(val);
  };

  return (
    <DialogWrapper title={title} borderColor={colors.primary}>
      <Text>{prompt}</Text>
      <Box marginTop={1} borderStyle="single" borderColor={colors.focus} paddingX={1}>
        <TextInput
          value={value}
          onChange={setValue}
          onSubmit={handleSubmit}
          placeholder={placeholder}
          focus={isActive}
        />
      </Box>
      <Box marginTop={1}>
        <Text color={colors.textMuted}>Enter to submit • Esc to cancel</Text>
      </Box>
    </DialogWrapper>
  );
}

/**
 * Props for ConfirmDialog component.
 */
interface ConfirmDialogProps {
  /** Dialog title */
  title: string;
  /** Confirmation message */
  message: string;
  /** Confirm handler */
  onConfirm: () => void;
  /** Cancel handler */
  onCancel: () => void;
  /** Whether dialog is visible/active */
  isActive?: boolean;
  /** Confirm button label */
  confirmLabel?: string;
  /** Cancel button label */
  cancelLabel?: string;
}

/**
 * Confirmation dialog with Yes/No options.
 */
export function ConfirmDialog({
  title,
  message,
  onConfirm,
  onCancel,
  isActive = true,
  confirmLabel = 'Yes',
  cancelLabel = 'No',
}: ConfirmDialogProps): React.ReactElement {
  const [selected, setSelected] = useState<'confirm' | 'cancel'>('confirm');

  useInput((input, key) => {
    if (!isActive) return;

    if (key.leftArrow || key.rightArrow || key.tab) {
      setSelected(prev => prev === 'confirm' ? 'cancel' : 'confirm');
    } else if (key.return) {
      if (selected === 'confirm') {
        onConfirm();
      } else {
        onCancel();
      }
    } else if (key.escape || input === 'n' || input === 'N') {
      onCancel();
    } else if (input === 'y' || input === 'Y') {
      onConfirm();
    }
  }, { isActive });

  return (
    <DialogWrapper title={title} borderColor={colors.warning}>
      <Text wrap="wrap">{message}</Text>
      <Box marginTop={1} gap={2}>
        <Text
          backgroundColor={selected === 'confirm' ? colors.focus : colors.secondary}
          color={selected === 'confirm' ? colors.bg : colors.text}
          bold={selected === 'confirm'}
        >
          {` ${confirmLabel} `}
        </Text>
        <Text
          backgroundColor={selected === 'cancel' ? colors.focus : colors.secondary}
          color={selected === 'cancel' ? colors.bg : colors.text}
          bold={selected === 'cancel'}
        >
          {` ${cancelLabel} `}
        </Text>
      </Box>
      <Box marginTop={1}>
        <Text color={colors.textMuted}>Y/N or Tab to switch • Enter to select</Text>
      </Box>
    </DialogWrapper>
  );
}

/**
 * Props for MessageDialog component.
 */
interface MessageDialogProps {
  /** Dialog title */
  title: string;
  /** Message content */
  message: string;
  /** Close handler */
  onClose: () => void;
  /** Dialog type for styling */
  type?: 'info' | 'error' | 'success';
  /** Whether dialog is visible/active */
  isActive?: boolean;
}

/**
 * Simple message dialog (info, error, success).
 */
export function MessageDialog({
  title,
  message,
  onClose,
  type = 'info',
  isActive = true,
}: MessageDialogProps): React.ReactElement {
  useInput((input, key) => {
    if (!isActive) return;
    
    if (key.return || key.escape) {
      onClose();
    }
  }, { isActive });

  const borderColor = type === 'error' ? colors.error :
                      type === 'success' ? colors.success :
                      colors.info;

  const icon = type === 'error' ? '✗' :
               type === 'success' ? '✓' :
               'ℹ';

  return (
    <DialogWrapper title={`${icon} ${title}`} borderColor={borderColor}>
      <Text wrap="wrap">{message}</Text>
      <Box marginTop={1}>
        <Text color={colors.textMuted}>Press Enter or Esc to close</Text>
      </Box>
    </DialogWrapper>
  );
}
