import { useState, useRef, useEffect, forwardRef, useImperativeHandle, useCallback } from 'react';
import { ArrowUp } from 'lucide-react';
import { readInputDraft, writeInputDraft } from '@/hooks/useAIChat';

export interface ChatInputBoxHandle {
  getValue: () => string;
  setValue: (v: string) => void;
  clear: () => void;
  focus: () => void;
}

type ChatInputBoxVariant = 'panel' | 'floating' | 'comment';

interface ChatInputBoxProps {
  cacheKey: string;
  isStreaming: boolean;
  onSend: (message: string) => void;
  placeholder?: string;
  autoFocus?: boolean;
  variant?: ChatInputBoxVariant;
}

const VARIANT_STYLES = {
  panel: {
    container: 'flex items-center gap-2 px-4 py-2.5',
    textarea: 'flex-1 resize-none bg-transparent text-sm placeholder:text-muted-foreground outline-none max-h-[7.5rem] overflow-y-auto',
    button: 'flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-primary text-primary-foreground shadow-sm transition-all hover:bg-primary/90 active:scale-95 disabled:opacity-40 disabled:cursor-not-allowed disabled:active:scale-100',
    iconSize: 16,
  },
  floating: {
    container: 'flex items-center gap-2 px-3 py-2.5',
    textarea: 'flex-1 resize-none bg-transparent text-sm placeholder:text-muted-foreground/60 outline-none max-h-20 overflow-y-auto',
    button: 'flex h-7 w-7 shrink-0 items-center justify-center rounded-xl bg-primary text-primary-foreground shadow-sm transition-all hover:bg-primary/90 active:scale-95 disabled:opacity-30 disabled:cursor-not-allowed',
    iconSize: 14,
  },
  comment: {
    container: 'flex items-center gap-2 px-3 py-2',
    textarea: 'flex-1 resize-none bg-transparent text-sm placeholder:text-muted-foreground outline-none max-h-32 overflow-y-auto',
    button: 'flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-primary text-primary-foreground shadow-sm transition-all hover:bg-primary/90 active:scale-95 disabled:opacity-30 disabled:cursor-not-allowed',
    iconSize: 14,
  },
} as const;

export const ChatInputBox = forwardRef<ChatInputBoxHandle, ChatInputBoxProps>(
  ({ cacheKey, isStreaming, onSend, placeholder, autoFocus, variant = 'panel' }, ref) => {
    const styles = VARIANT_STYLES[variant];
    const [value, setValue] = useState(() => readInputDraft(cacheKey));
    const textareaRef = useRef<HTMLTextAreaElement>(null);
    const valueRef = useRef(value);
    valueRef.current = value;

    // Re-init when the cache key changes (context switches in FloatingChat).
    const prevKeyRef = useRef(cacheKey);
    useEffect(() => {
      if (prevKeyRef.current !== cacheKey) {
        prevKeyRef.current = cacheKey;
        setValue(readInputDraft(cacheKey));
      }
    }, [cacheKey]);

    // Debounced draft persistence — fires 250 ms after the last keystroke.
    useEffect(() => {
      const id = setTimeout(() => writeInputDraft(cacheKey, value), 250);
      return () => clearTimeout(id);
    }, [cacheKey, value]);

    // Flush on unmount so a fast close/reopen preserves the current draft.
    useEffect(() => {
      return () => writeInputDraft(cacheKey, valueRef.current);
    }, [cacheKey]);

    useImperativeHandle(ref, () => ({
      getValue: () => valueRef.current,
      setValue: (v: string) => {
        setValue(v);
        // Move caret to end + focus after React commits the new value.
        requestAnimationFrame(() => {
          const el = textareaRef.current;
          if (el) {
            el.focus();
            el.setSelectionRange(v.length, v.length);
          }
        });
      },
      clear: () => setValue(''),
      focus: () => textareaRef.current?.focus(),
    }));

    const handleKeyDown = useCallback(
      (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
        // Guard IME composition — prevents spurious submit during Italian dead-key
        // input (e.g. ` + e → è) and CJK composition sequences.
        if (e.nativeEvent.isComposing || e.keyCode === 229) return;
        if (e.key === 'Enter' && !e.shiftKey) {
          e.preventDefault();
          if (isStreaming) return;
          const v = valueRef.current.trim();
          if (!v) return;
          setValue('');
          writeInputDraft(cacheKey, '');
          onSend(v);
        }
      },
      [isStreaming, onSend, cacheKey],
    );

    const handleClick = useCallback(() => {
      if (isStreaming) return;
      const v = valueRef.current.trim();
      if (!v) return;
      setValue('');
      writeInputDraft(cacheKey, '');
      onSend(v);
    }, [isStreaming, onSend, cacheKey]);

    return (
      <div className={styles.container}>
        <textarea
          ref={textareaRef}
          value={value}
          onChange={(e) => setValue(e.target.value)}
          onKeyDown={handleKeyDown}
          placeholder={placeholder}
          aria-label="Chat message"
          rows={1}
          autoFocus={autoFocus}
          className={styles.textarea}
          style={{ fieldSizing: 'content' } as React.CSSProperties}
        />
        <button
          type="button"
          onClick={handleClick}
          disabled={!value.trim() || isStreaming}
          aria-label="Send message"
          className={styles.button}
        >
          <ArrowUp size={styles.iconSize} />
        </button>
      </div>
    );
  },
);
ChatInputBox.displayName = 'ChatInputBox';
