'use client';

import { useState, useEffect, useRef } from 'react';
import type { ProviderConfig, ProviderId } from '@/types';
import { PROVIDERS, PROVIDER_MAP } from '@/lib/providers';

type ConnectStatus = 'idle' | 'loading' | 'success' | 'error';

interface Props {
  config: ProviderConfig;
  onSave: (config: ProviderConfig) => void;
  onClose: () => void;
}

export default function ProviderSettings({ config, onSave, onClose }: Props) {
  const [provider, setProvider] = useState<ProviderId>(config.provider);
  const [model, setModel] = useState(config.model);
  const [apiKey, setApiKey] = useState(config.apiKey ?? '');
  const [baseUrl, setBaseUrl] = useState(config.baseUrl ?? '');

  const [connectStatus, setConnectStatus] = useState<ConnectStatus>('idle');
  const [connectError, setConnectError] = useState('');
  const [fetchedModels, setFetchedModels] = useState<string[]>([]);
  const [modelFilter, setModelFilter] = useState('');
  const filterRef = useRef<HTMLInputElement>(null);

  const def = PROVIDER_MAP[provider];

  // Reset when provider changes
  useEffect(() => {
    const newDef = PROVIDER_MAP[provider];
    setModel(newDef.defaultModel);
    setBaseUrl(newDef.hasCustomBaseUrl ? newDef.defaultBaseUrl : '');
    if (!newDef.requiresApiKey) setApiKey('');
    setConnectStatus('idle');
    setFetchedModels([]);
    setModelFilter('');
  }, [provider]);

  // Focus filter when models load
  useEffect(() => {
    if (connectStatus === 'success') {
      setTimeout(() => filterRef.current?.focus(), 50);
    }
  }, [connectStatus]);

  async function handleConnect() {
    setConnectStatus('loading');
    setConnectError('');
    setFetchedModels([]);

    try {
      const res = await fetch('/api/models', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          provider,
          apiKey: apiKey.trim() || undefined,
          baseUrl: baseUrl.trim() || undefined,
        }),
      });

      const data = await res.json();

      if (!res.ok || data.error) {
        setConnectError(data.error ?? `Error ${res.status}`);
        setConnectStatus('error');
        return;
      }

      const models: string[] = data.models ?? [];
      setFetchedModels(models);
      setConnectStatus('success');
      // Auto-select first model if current isn't in the fetched list
      if (models.length && !models.includes(model)) {
        setModel(models[0]);
      }
    } catch (err) {
      setConnectError(err instanceof Error ? err.message : 'Connection failed');
      setConnectStatus('error');
    }
  }

  function handleSave() {
    const saved: ProviderConfig = {
      provider,
      model: model.trim() || def.defaultModel,
      ...(apiKey.trim() ? { apiKey: apiKey.trim() } : {}),
      ...(baseUrl.trim() && def.hasCustomBaseUrl ? { baseUrl: baseUrl.trim() } : {}),
    };
    onSave(saved);
    onClose();
  }

  const filteredModels = fetchedModels.filter((m) =>
    m.toLowerCase().includes(modelFilter.toLowerCase())
  );

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm"
      onClick={(e) => e.target === e.currentTarget && onClose()}
    >
      <div className="w-full max-w-md rounded-2xl border border-zinc-700 bg-zinc-900 shadow-2xl">
        {/* Header */}
        <div className="flex items-center justify-between border-b border-zinc-700 px-6 py-4">
          <h2 className="text-sm font-semibold text-zinc-100">AI Provider Settings</h2>
          <button
            onClick={onClose}
            className="rounded-lg p-1 text-zinc-400 hover:bg-zinc-800 hover:text-zinc-200 transition-colors"
            aria-label="Close"
          >
            <svg className="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
              <path d="M18 6 6 18M6 6l12 12" />
            </svg>
          </button>
        </div>

        {/* Body */}
        <div className="space-y-5 px-6 py-5">

          {/* Provider selector */}
          <div>
            <label className="mb-2 block text-xs font-medium text-zinc-400">Provider</label>
            <div className="grid grid-cols-2 gap-2">
              {PROVIDERS.map((p) => (
                <button
                  key={p.id}
                  onClick={() => setProvider(p.id)}
                  className={`rounded-lg border px-3 py-2.5 text-left text-xs transition-all ${
                    provider === p.id
                      ? 'border-blue-500 bg-blue-600/20 text-blue-300'
                      : 'border-zinc-700 bg-zinc-800 text-zinc-400 hover:border-zinc-600 hover:text-zinc-200'
                  }`}
                >
                  <span className="block font-semibold">{p.label}</span>
                  <span className="block text-[10px] opacity-70 mt-0.5">
                    {p.requiresApiKey ? 'Requires API key' : 'Local — no key needed'}
                  </span>
                </button>
              ))}
            </div>
          </div>

          {/* API Key — shown before model so user fills it first */}
          {def.requiresApiKey && (
            <div>
              <label className="mb-2 block text-xs font-medium text-zinc-400">
                API Key
                {provider === 'anthropic' && (
                  <span className="ml-1 text-zinc-600">(leave blank to use ANTHROPIC_API_KEY env var)</span>
                )}
              </label>
              <input
                type="password"
                value={apiKey}
                onChange={(e) => {
                  setApiKey(e.target.value);
                  setConnectStatus('idle');
                  setFetchedModels([]);
                }}
                placeholder={provider === 'anthropic' ? 'sk-ant-…  (optional)' : 'sk-or-…'}
                autoComplete="off"
                className="w-full rounded-lg border border-zinc-700 bg-zinc-800 px-3 py-2 text-xs text-zinc-200 placeholder-zinc-600 focus:border-blue-500 focus:outline-none"
              />
            </div>
          )}

          {/* Base URL */}
          {def.hasCustomBaseUrl && (
            <div>
              <label className="mb-2 block text-xs font-medium text-zinc-400">Base URL</label>
              <input
                type="text"
                value={baseUrl}
                onChange={(e) => {
                  setBaseUrl(e.target.value);
                  setConnectStatus('idle');
                  setFetchedModels([]);
                }}
                placeholder={def.defaultBaseUrl}
                className="w-full rounded-lg border border-zinc-700 bg-zinc-800 px-3 py-2 text-xs text-zinc-200 placeholder-zinc-600 focus:border-blue-500 focus:outline-none"
              />
              <p className="mt-1 text-[11px] text-zinc-600">
                {provider === 'ollama'
                  ? 'Ollama must be running with OLLAMA_ORIGINS=* for CORS.'
                  : 'LM Studio server must be running on this address.'}
              </p>
            </div>
          )}

          {/* Model */}
          <div>
            <div className="mb-2 flex items-center justify-between">
              <label className="text-xs font-medium text-zinc-400">Model</label>
              <button
                onClick={handleConnect}
                disabled={connectStatus === 'loading'}
                className={`flex items-center gap-1.5 rounded-md px-2.5 py-1 text-xs font-medium transition-colors disabled:cursor-not-allowed ${
                  connectStatus === 'success'
                    ? 'bg-green-900/40 text-green-400 hover:bg-green-900/60'
                    : 'bg-zinc-700 text-zinc-300 hover:bg-zinc-600 disabled:opacity-60'
                }`}
              >
                {connectStatus === 'loading' ? (
                  <>
                    <div className="h-3 w-3 animate-spin rounded-full border border-zinc-500 border-t-zinc-200" />
                    Connecting…
                  </>
                ) : connectStatus === 'success' ? (
                  <>
                    <svg className="h-3 w-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2.5}>
                      <path d="M20 6 9 17l-5-5" />
                    </svg>
                    {fetchedModels.length} model{fetchedModels.length !== 1 ? 's' : ''} · Reconnect
                  </>
                ) : (
                  <>
                    <svg className="h-3 w-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
                      <path d="M5 12h14M12 5l7 7-7 7" />
                    </svg>
                    Connect
                  </>
                )}
              </button>
            </div>

            {/* Error */}
            {connectStatus === 'error' && (
              <div className="mb-2 rounded-lg border border-red-800 bg-red-900/20 px-3 py-2 text-xs text-red-400">
                {connectError}
              </div>
            )}

            {/* Live model list */}
            {connectStatus === 'success' && fetchedModels.length > 0 ? (
              <div className="space-y-1.5">
                {fetchedModels.length > 8 && (
                  <input
                    ref={filterRef}
                    type="text"
                    value={modelFilter}
                    onChange={(e) => setModelFilter(e.target.value)}
                    placeholder={`Filter ${fetchedModels.length} models…`}
                    className="w-full rounded-lg border border-zinc-700 bg-zinc-800 px-3 py-2 text-xs text-zinc-200 placeholder-zinc-600 focus:border-blue-500 focus:outline-none"
                  />
                )}
                <div className="max-h-52 overflow-y-auto rounded-lg border border-zinc-700 bg-zinc-800">
                  {filteredModels.length === 0 ? (
                    <p className="px-3 py-3 text-xs italic text-zinc-500">No models match &ldquo;{modelFilter}&rdquo;</p>
                  ) : (
                    filteredModels.map((m) => (
                      <button
                        key={m}
                        onClick={() => setModel(m)}
                        className={`flex w-full items-center gap-2 px-3 py-2 text-left text-xs transition-colors ${
                          m === model
                            ? 'bg-blue-600/20 text-blue-300'
                            : 'text-zinc-300 hover:bg-zinc-700'
                        }`}
                      >
                        {m === model ? (
                          <svg className="h-3 w-3 flex-shrink-0 text-blue-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2.5}>
                            <path d="M20 6 9 17l-5-5" />
                          </svg>
                        ) : (
                          <span className="h-3 w-3 flex-shrink-0" />
                        )}
                        <span className="font-mono">{m}</span>
                      </button>
                    ))
                  )}
                </div>
                {modelFilter && filteredModels.length < fetchedModels.length && (
                  <p className="text-right text-[11px] text-zinc-600">
                    {filteredModels.length} of {fetchedModels.length} shown
                  </p>
                )}
              </div>
            ) : (
              /* Static fallback — shown before connecting or on error */
              <div className="space-y-1.5">
                {def.modelSuggestions.length > 0 ? (
                  <>
                    <select
                      value={def.modelSuggestions.includes(model) ? model : '__custom__'}
                      onChange={(e) => {
                        if (e.target.value !== '__custom__') setModel(e.target.value);
                      }}
                      className="w-full rounded-lg border border-zinc-700 bg-zinc-800 px-3 py-2 text-xs text-zinc-200 focus:border-blue-500 focus:outline-none"
                    >
                      {def.modelSuggestions.map((m) => (
                        <option key={m} value={m}>{m}</option>
                      ))}
                      <option value="__custom__">Custom…</option>
                    </select>
                    {!def.modelSuggestions.includes(model) && (
                      <input
                        type="text"
                        value={model}
                        onChange={(e) => setModel(e.target.value)}
                        placeholder={def.defaultModel}
                        className="w-full rounded-lg border border-zinc-700 bg-zinc-800 px-3 py-2 text-xs text-zinc-200 placeholder-zinc-600 focus:border-blue-500 focus:outline-none"
                      />
                    )}
                  </>
                ) : (
                  <input
                    type="text"
                    value={model}
                    onChange={(e) => setModel(e.target.value)}
                    placeholder={def.defaultModel}
                    className="w-full rounded-lg border border-zinc-700 bg-zinc-800 px-3 py-2 text-xs text-zinc-200 placeholder-zinc-600 focus:border-blue-500 focus:outline-none"
                  />
                )}
                <p className="text-[11px] text-zinc-600">
                  Hit Connect to load available models from {def.label}.
                </p>
              </div>
            )}

            {connectStatus === 'success' && (
              <p className="mt-1.5 text-[11px] text-zinc-500">
                Selected: <span className="font-mono text-zinc-400">{model}</span>
              </p>
            )}
          </div>
        </div>

        {/* Footer */}
        <div className="flex justify-end gap-2 border-t border-zinc-700 px-6 py-4">
          <button
            onClick={onClose}
            className="rounded-lg px-4 py-2 text-xs text-zinc-400 hover:bg-zinc-800 hover:text-zinc-200 transition-colors"
          >
            Cancel
          </button>
          <button
            onClick={handleSave}
            className="rounded-lg bg-blue-600 px-4 py-2 text-xs font-semibold text-white hover:bg-blue-500 transition-colors"
          >
            Save
          </button>
        </div>
      </div>
    </div>
  );
}
