import { useState, useEffect } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { RefreshCw } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { useClient } from 'hooks/useClient';

type OcrConfig = {
  url: string;
  model: string;
};

export const OCRSection = () => {
  const client = useClient();
  const queryClient = useQueryClient();

  const { data: config, isLoading } = useQuery({
    queryKey: ['OCR_CONFIG'],
    queryFn: () => client.get<OcrConfig | null>('/server-settings/ocr'),
  });

  const [url, setUrl] = useState('http://localhost:64203');
  const [model, setModel] = useState('Qwen2.5-VL-7B-Instruct-q4_k_m.gguf');
  const [models, setModels] = useState<string[]>([]);
  const [modelsLoading, setModelsLoading] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [isTesting, setIsTesting] = useState(false);

  const fetchModels = async (u: string) => {
    setModelsLoading(true);
    try {
      const res = await client.get<{ models?: string[]; error?: string }>(
        `/server-settings/ocr/models?url=${encodeURIComponent(u)}`,
      );
      if (res.models) setModels(res.models);
      else setModels([]);
    } catch {
      setModels([]);
    } finally {
      setModelsLoading(false);
    }
  };

  useEffect(() => {
    if (!config) return;
    setUrl(config.url);
    setModel(config.model);
    fetchModels(config.url);
  }, [config]);

  const handleSave = async () => {
    if (isSaving) return;
    setIsSaving(true);
    try {
      await client.put('/server-settings/ocr', { url, model });
      queryClient.invalidateQueries({ queryKey: ['OCR_CONFIG'] });
      toast.success('OCR settings saved');
    } catch {
      toast.error('Failed to save OCR settings');
    } finally {
      setIsSaving(false);
    }
  };

  const handleTest = async () => {
    if (isTesting) return;
    setIsTesting(true);
    try {
      const res = await client.post<{ success?: boolean; error?: string }>('/server-settings/ocr/test', { url, model });
      if (res.error) {
        toast.error(res.error);
      } else {
        toast.success('Vision model server is reachable');
      }
    } catch (err: unknown) {
      const raw = (err as { message?: string })?.message;
      let msg = 'Connection failed';
      try {
        if (raw) msg = JSON.parse(raw).error ?? msg;
      } catch {
        /* ignore */
      }
      toast.error(msg);
    } finally {
      setIsTesting(false);
    }
  };

  if (isLoading) return <p className="text-sm text-duck-dark/40">Loading...</p>;

  return (
    <div className="grid gap-4">
      <Label className="grid gap-2">
        <span className="text-duck-dark/70 dark:text-foreground/70">Vision Model Server URL</span>
        <Input
          className="h-11 bg-background/60 border-duck-dark/20 text-duck-dark dark:text-foreground placeholder:text-duck-dark/40"
          placeholder="http://localhost:64203"
          value={url}
          onChange={(ev) => setUrl(ev.target.value)}
        />
      </Label>

      <Label className="grid gap-2">
        <div className="flex items-center gap-1.5">
          <span className="text-duck-dark/70 dark:text-foreground/70">Model</span>
          <button
            type="button"
            onClick={() => fetchModels(url)}
            disabled={modelsLoading}
            className="p-0.5 rounded hover:bg-duck-dark/10 dark:hover:bg-foreground/10 cursor-pointer transition-colors disabled:opacity-40"
            title="Refresh models"
          >
            <RefreshCw
              className={`h-3 w-3 text-duck-dark/50 dark:text-foreground/50 ${modelsLoading ? 'animate-spin' : ''}`}
            />
          </button>
        </div>
        {models.length > 0 ? (
          <Select value={model} onValueChange={setModel}>
            <SelectTrigger className="h-11 bg-background/60 border-duck-dark/20 text-duck-dark dark:text-foreground">
              <SelectValue placeholder="Select a model" />
            </SelectTrigger>
            <SelectContent className="z-[600] max-h-[300px]">
              {models.map((m) => (
                <SelectItem key={m} value={m}>
                  {m}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        ) : (
          <Input
            className="h-11 bg-background/60 border-duck-dark/20 text-duck-dark dark:text-foreground placeholder:text-duck-dark/40"
            placeholder="Qwen2.5-VL-7B-Instruct-q4_k_m.gguf"
            value={model}
            onChange={(ev) => setModel(ev.target.value)}
          />
        )}
      </Label>

      <div className="flex items-center gap-2">
        <Button
          type="button"
          onClick={handleSave}
          disabled={isSaving}
          className="flex-1 h-11 bg-duck-yellow hover:bg-duck-yellow/90 text-duck-teal font-bold transition-all duration-200 hover:scale-105 cursor-pointer disabled:opacity-50 disabled:hover:scale-100"
        >
          {isSaving ? 'Saving...' : 'Save'}
        </Button>
        <Button
          type="button"
          variant="outline"
          onClick={handleTest}
          disabled={isTesting}
          className="h-11 cursor-pointer disabled:opacity-50"
        >
          {isTesting ? 'Testing...' : 'Test'}
        </Button>
      </div>
    </div>
  );
};
