import { useEffect, useMemo, useRef, useState } from 'react';
import type { ModelInfo } from '@/lib/types';

interface ChatInputProps {
  onSend: (content: string, options?: { modelId?: string }) => void;
  onStop?: () => void;
  isStreaming?: boolean;
  models: ModelInfo[];
  selectedModelId: string;
  onModelChange: (modelId: string) => void;
  onRequestEditLastMessage?: () => string | null;
}

const MAX_HEIGHT = 220;

export function ChatInput({
  onSend,
  onStop,
  isStreaming = false,
  models,
  selectedModelId,
  onModelChange,
  onRequestEditLastMessage,
}: ChatInputProps): React.ReactElement {
  const [value, setValue] = useState('');
  const textareaRef = useRef<HTMLTextAreaElement>(null);
  const selectedModel = useMemo(
    () => models.find((model) => model.id === selectedModelId) ?? models[0],
    [models, selectedModelId],
  );

  useEffect(() => {
    const textarea = textareaRef.current;
    if (!textarea) return;
    textarea.style.height = 'auto';
    textarea.style.height = `${Math.min(textarea.scrollHeight, MAX_HEIGHT)}px`;
  }, [value]);

  useEffect(() => {
    function handleGlobalFocus(event: KeyboardEvent): void {
      if (
        (event.metaKey || event.ctrlKey) &&
        (event.key === '/' || event.key.toLowerCase() === 'k')
      ) {
        const target = event.target as HTMLElement | null;
        if (target?.closest('input, textarea, [contenteditable="true"]')) return;
        event.preventDefault();
        textareaRef.current?.focus();
      }
    }

    document.addEventListener('keydown', handleGlobalFocus);
    return () => document.removeEventListener('keydown', handleGlobalFocus);
  }, []);

  function handleSubmit(event: React.FormEvent): void {
    event.preventDefault();
    const trimmed = value.trim();
    if (!trimmed || isStreaming) return;
    onSend(trimmed, { modelId: selectedModel?.id });
    setValue('');
    textareaRef.current?.focus();
  }

  function handleKeyDown(event: React.KeyboardEvent<HTMLTextAreaElement>): void {
    if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) {
      event.preventDefault();
      handleSubmit(event);
      return;
    }

    if (event.key === 'ArrowUp' && value.length === 0 && onRequestEditLastMessage) {
      const lastMessage = onRequestEditLastMessage();
      if (lastMessage) {
        event.preventDefault();
        setValue(lastMessage);
      }
    }
  }

  const charCount = value.length;
  const tokenEstimate = Math.ceil(charCount / 4);

  return (
    <form
      onSubmit={handleSubmit}
      className="border-t px-4 py-4 backdrop-blur-xl md:px-6"
      style={{
        backgroundColor: 'color-mix(in srgb, var(--color-surface) 88%, transparent)',
        borderColor: 'var(--color-border)',
      }}
    >
      <div
        className="rounded-[28px] border p-3 shadow-[var(--shadow-ms-lg)]"
        style={{
          backgroundColor: 'var(--color-surface-2)',
          borderColor: 'var(--color-border)',
        }}
      >
        <div className="mb-3 flex flex-wrap items-center gap-3">
          <label className="flex min-w-0 items-center gap-2 text-xs text-[var(--color-muted)]">
            <span className="uppercase tracking-[0.18em]">Model</span>
            <select
              value={selectedModelId}
              onChange={(event) => onModelChange(event.target.value)}
              className="rounded-full border px-3 py-1.5 text-sm outline-none"
              style={{
                backgroundColor: 'var(--color-surface)',
                borderColor: 'var(--color-border)',
                color: 'var(--color-text)',
              }}
            >
              {models.map((model) => (
                <option key={`${model.provider}:${model.id}`} value={model.id}>
                  {model.name} · {model.provider}
                </option>
              ))}
            </select>
          </label>
          <div className="ml-auto hidden items-center gap-2 text-xs text-[var(--color-muted)] md:flex">
            <span className="rounded-full border border-[var(--color-border)] px-2 py-1">
              ⌘/ focus
            </span>
            <span className="rounded-full border border-[var(--color-border)] px-2 py-1">
              ⌘K focus
            </span>
            <span className="rounded-full border border-[var(--color-border)] px-2 py-1">
              ⌘↵ send
            </span>
          </div>
        </div>

        <div className="flex items-end gap-3">
          <textarea
            ref={textareaRef}
            value={value}
            onChange={(event) => setValue(event.target.value)}
            onKeyDown={handleKeyDown}
            disabled={isStreaming}
            rows={1}
            placeholder="Ask Mosaic something..."
            className="min-h-[3.25rem] flex-1 resize-none bg-transparent px-1 py-2 text-sm outline-none placeholder:text-[var(--color-muted)] disabled:opacity-60"
            style={{
              color: 'var(--color-text)',
              maxHeight: `${MAX_HEIGHT}px`,
            }}
          />

          {isStreaming ? (
            <button
              type="button"
              onClick={onStop}
              className="inline-flex h-11 items-center gap-2 rounded-full border px-4 text-sm font-medium transition-colors"
              style={{
                backgroundColor: 'var(--color-surface)',
                borderColor: 'var(--color-border)',
                color: 'var(--color-text)',
              }}
            >
              <span className="inline-block h-2.5 w-2.5 rounded-sm bg-[var(--color-danger)]" />
              Stop
            </button>
          ) : (
            <button
              type="submit"
              disabled={!value.trim()}
              className="inline-flex h-11 items-center gap-2 rounded-full px-4 text-sm font-semibold text-white transition-all disabled:cursor-not-allowed disabled:opacity-45"
              style={{ backgroundColor: 'var(--color-ms-blue-500)' }}
            >
              <span>Send</span>
              <span aria-hidden="true">↗</span>
            </button>
          )}
        </div>

        <div className="mt-3 flex flex-wrap items-center gap-2 text-xs text-[var(--color-muted)]">
          <span>{charCount.toLocaleString()} chars</span>
          <span>·</span>
          <span>~{tokenEstimate.toLocaleString()} tokens</span>
          {selectedModel ? (
            <>
              <span>·</span>
              <span>{selectedModel.reasoning ? 'Reasoning on' : 'Fast response'}</span>
            </>
          ) : null}
          <span className="ml-auto">Shift+Enter newline · Arrow ↑ edit last</span>
        </div>
      </div>
    </form>
  );
}
