import { useState, useRef, useEffect } from 'react';
import { ChevronDown, Globe } from 'lucide-react';
import type { LLMProvider } from '../../../../types/app';
import SessionProviderLogo from '../../../llm-logo-provider/SessionProviderLogo';

type ModelOption = { value: string; label: string };

interface ModelSelectorBarProps {
  provider: LLMProvider;
  claudeModel: string;
  setClaudeModel: (model: string) => void;
  cursorModel: string;
  setCursorModel: (model: string) => void;
  codexModel: string;
  setCodexModel: (model: string) => void;
  geminiModel: string;
  setGeminiModel: (model: string) => void;
  claudeModelOptions: ModelOption[];
  codexModelOptions: ModelOption[];
  geminiModelOptions: ModelOption[];
  cursorModelOptions: ModelOption[];
}

function useCurrentModel(
  provider: LLMProvider,
  claudeModel: string,
  cursorModel: string,
  codexModel: string,
  geminiModel: string,
  claudeModelOptions: ModelOption[],
  codexModelOptions: ModelOption[],
  geminiModelOptions: ModelOption[],
  cursorModelOptions: ModelOption[],
): { value: string; label: string; options: ModelOption[] } {
  const map: Record<LLMProvider, { value: string; options: ModelOption[] }> = {
    claude: { value: claudeModel, options: claudeModelOptions },
    cursor: { value: cursorModel, options: cursorModelOptions },
    codex: { value: codexModel, options: codexModelOptions },
    gemini: { value: geminiModel, options: geminiModelOptions },
  };
  const { value, options } = map[provider] ?? map.claude;
  const label = options.find((o) => o.value === value)?.label ?? value;
  return { value, label, options };
}

export default function ModelSelectorBar({
  provider,
  claudeModel,
  setClaudeModel,
  cursorModel,
  setCursorModel,
  codexModel,
  setCodexModel,
  geminiModel,
  setGeminiModel,
  claudeModelOptions,
  codexModelOptions,
  geminiModelOptions,
  cursorModelOptions,
}: ModelSelectorBarProps) {
  const [open, setOpen] = useState(false);
  const [search, setSearch] = useState('');
  const dropdownRef = useRef<HTMLDivElement>(null);
  const searchRef = useRef<HTMLInputElement>(null);

  const { value, label, options } = useCurrentModel(
    provider, claudeModel, cursorModel, codexModel, geminiModel,
    claudeModelOptions, codexModelOptions, geminiModelOptions, cursorModelOptions,
  );

  const filtered = search.trim()
    ? options.filter((o) => o.label.toLowerCase().includes(search.toLowerCase()))
    : options;

  // Close on outside click (use click, not mousedown, so item selection fires first)
  useEffect(() => {
    if (!open) return;
    const handler = (e: MouseEvent) => {
      if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {
        setOpen(false);
        setSearch('');
      }
    };
    document.addEventListener('click', handler);
    return () => document.removeEventListener('click', handler);
  }, [open]);

  useEffect(() => {
    if (open) setTimeout(() => searchRef.current?.focus(), 50);
  }, [open]);

  const handleSelect = (modelValue: string) => {
    const setters: Record<LLMProvider, (v: string) => void> = {
      claude: setClaudeModel,
      cursor: setCursorModel,
      codex: setCodexModel,
      gemini: setGeminiModel,
    };
    setters[provider]?.(modelValue);
    localStorage.setItem(`${provider}-model`, modelValue);
    setOpen(false);
    setSearch('');
  };

  return (
    <div className="relative z-40 flex-shrink-0 flex items-center justify-between px-4 py-1.5 border-b border-border/40 bg-muted/20 backdrop-blur-sm">
      {/* Left: provider label */}
      <div className="flex items-center gap-2 text-xs text-muted-foreground">
        <SessionProviderLogo provider={provider} className="h-3.5 w-3.5" />
        <span className="capitalize">{provider}</span>
      </div>

      {/* Right: model picker */}
      <div className="relative" ref={dropdownRef}>
        <button
          type="button"
          onClick={() => setOpen((o) => !o)}
          className="flex items-center gap-1.5 rounded-md border border-border/50 bg-background/60 px-2.5 py-1 text-xs text-foreground hover:bg-accent hover:border-border transition-all"
        >
          <Globe className="h-3 w-3 text-muted-foreground" />
          <span className="max-w-[180px] truncate">{label}</span>
          <ChevronDown className={`h-3 w-3 text-muted-foreground transition-transform duration-150 ${open ? 'rotate-180' : ''}`} />
        </button>

        {open && (
          <div className="absolute right-0 top-full mt-1.5 z-[100] w-64 rounded-xl border border-border/60 bg-card shadow-2xl overflow-hidden">
            <div className="p-2 border-b border-border/40">
              <input
                ref={searchRef}
                type="text"
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                onClick={(e) => e.stopPropagation()}
                placeholder="Search models..."
                className="w-full rounded-lg bg-muted/50 px-2.5 py-1.5 text-xs text-foreground placeholder:text-muted-foreground/50 outline-none border border-border/40 focus:border-border"
              />
            </div>
            <div className="max-h-64 overflow-y-auto py-1">
              {filtered.length === 0 ? (
                <p className="px-3 py-2 text-xs text-muted-foreground">No models found</p>
              ) : (
                filtered.map((opt) => (
                  <button
                    key={opt.value}
                    type="button"
                    onMouseDown={(e) => {
                      // Fire on mousedown so selection wins before any blur/outside-click handler
                      e.preventDefault();
                      e.stopPropagation();
                      handleSelect(opt.value);
                    }}
                    className={`w-full text-left px-3 py-1.5 text-xs transition-colors hover:bg-accent/60 cursor-pointer ${
                      opt.value === value ? 'text-primary font-medium' : 'text-foreground'
                    }`}
                  >
                    <span className="truncate block">{opt.label}</span>
                    {opt.value === value && (
                      <span className="text-[10px] text-muted-foreground block">{opt.value}</span>
                    )}
                  </button>
                ))
              )}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
