import { useState, useEffect, useMemo } from 'react';
import { toast } from 'sonner';
import { Terminal, Eye, Trash2 } from 'lucide-react';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Button } from '@/components/ui/button';
import { Textarea } from '@/components/ui/textarea';
import { Slider } from '@/components/ui/slider';
import { Switch } from '@/components/ui/switch';
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@/components/ui/accordion';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Card } from '@/components/Card';
import { DashboardLayout } from '../Layout';
import { useSettings } from '@/state/useSettings';
import { useUserState } from '@/state/useUserState';
import {
  useClaudeModels,
  useOpenCodeModels,
  useVisibleClaudeModels,
  useVisibleOpenCodeModels,
} from '@/state/useModels';
import type { UserSettings } from '@/state/types/user-settings';

export const AISettings = () => {
  const [mainTab, setMainTab] = useUserState('ai-settings-tab', 'chat-defaults');

  return (
    <DashboardLayout>
      <div className="flex justify-center h-full px-4 py-8 overflow-y-auto">
        <Card className="w-full max-w-2xl h-fit p-6">
          <Tabs value={mainTab} onValueChange={setMainTab}>
            <TabsList className="w-full mb-6">
              <TabsTrigger value="chat-defaults" className="flex-1 gap-2 cursor-pointer">
                <Terminal className="h-4 w-4" />
                Chat Defaults
              </TabsTrigger>
              <TabsTrigger value="model-visibility" className="flex-1 gap-2 cursor-pointer">
                <Eye className="h-4 w-4" />
                Model Visibility
              </TabsTrigger>
            </TabsList>

            <TabsContent value="chat-defaults">
              <ChatDefaultsSection />
            </TabsContent>

            <TabsContent value="model-visibility">
              <ModelVisibilitySection />
            </TabsContent>
          </Tabs>
        </Card>
      </div>
    </DashboardLayout>
  );
};

const ChatDefaultsSection = () => {
  const { settings, saveSettings } = useSettings();
  const claudeModels = useVisibleClaudeModels();
  const openCodeModels = useVisibleOpenCodeModels();
  const [isSaving, setIsSaving] = useState(false);

  const [model, setModel] = useState<string | null>(settings.chat.defaultModel);
  const [systemPrompt, setSystemPrompt] = useState(settings.chat.systemPrompt);
  const [temperature, setTemperature] = useState(settings.chat.temperature);
  const [defaultPwd, setDefaultPwd] = useState(settings.chat.defaultPwd);

  useEffect(() => {
    setModel(settings.chat.defaultModel);
    setSystemPrompt(settings.chat.systemPrompt);
    setTemperature(settings.chat.temperature);
    setDefaultPwd(settings.chat.defaultPwd);
  }, [settings]);

  const allModels = useMemo(
    () => [
      ...claudeModels.map((m) => ({ ...m, provider: 'Claude' })),
      ...openCodeModels.map((m) => ({ ...m, provider: m.provider ?? 'OpenCode' })),
    ],
    [claudeModels, openCodeModels],
  );

  const handleSave = async () => {
    if (isSaving) return;
    setIsSaving(true);
    try {
      const isOpenCode = openCodeModels.some((m) => m.id === model);
      const defaultProvider = isOpenCode ? ('opencode' as const) : ('claude' as const);
      const updated: UserSettings = {
        ...settings,
        chat: { defaultProvider, defaultModel: model, systemPrompt, temperature, defaultPwd },
      };
      await saveSettings(updated);
      toast.success('Chat defaults saved');
    } catch {
      toast.error('Failed to save settings');
    } finally {
      setIsSaving(false);
    }
  };

  return (
    <div className="grid gap-4">
      <Label className="grid gap-2">
        <span className="text-duck-dark/70">Model</span>
        <Select value={model ?? ''} onValueChange={(v) => setModel(v || null)}>
          <SelectTrigger className="h-11 bg-white/60 border-duck-dark/20 text-duck-dark">
            <SelectValue placeholder="Default" />
          </SelectTrigger>
          <SelectContent className="z-[600]">
            {allModels.map((m) => (
              <SelectItem key={`${m.provider}:${m.id}`} value={m.id}>
                <span className="font-bold">{m.name}</span>
                <span className="text-duck-dark/50 ml-1">({m.provider})</span>
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </Label>

      <Label className="grid gap-2">
        <span className="text-duck-dark/70">System Prompt</span>
        <Textarea
          className="bg-white/60 border-duck-dark/20 text-duck-dark placeholder:text-duck-dark/40 min-h-[100px]"
          placeholder="Custom instructions for the AI..."
          value={systemPrompt}
          onChange={(ev) => setSystemPrompt(ev.target.value)}
        />
      </Label>

      <Label className="grid gap-2">
        <div className="flex items-center justify-between">
          <span className="text-duck-dark/70">Temperature</span>
          <span className="text-sm text-duck-dark/50">{temperature.toFixed(1)}</span>
        </div>
        <Slider min={0} max={2} step={0.1} value={[temperature]} onValueChange={([v]) => setTemperature(v ?? 1)} />
      </Label>

      <Label className="grid gap-2">
        <span className="text-duck-dark/70">Default Working Directory</span>
        <Input
          className="h-11 bg-white/60 border-duck-dark/20 text-duck-dark placeholder:text-duck-dark/40"
          value={defaultPwd}
          onChange={(ev) => setDefaultPwd(ev.target.value)}
          placeholder="~"
        />
      </Label>

      <Button
        type="button"
        onClick={handleSave}
        disabled={isSaving}
        className="w-full 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>
    </div>
  );
};

const ModelVisibilitySection = () => {
  const { settings, saveSettings } = useSettings();
  const claudeModels = useClaudeModels();
  const openCodeModels = useOpenCodeModels();
  const [subTab, setSubTab] = useUserState('ai-settings-visibility-tab', 'opencode');

  const enabledModels = settings.ai?.enabledModels ?? [];
  const enabledProviders = settings.ai?.enabledProviders ?? [];

  const toggleModel = async (key: string) => {
    const isEnabled = enabledModels.includes(key);
    const newEnabled = isEnabled ? enabledModels.filter((id) => id !== key) : [...enabledModels, key];
    await saveSettings({ ...settings, ai: { ...settings.ai, enabledModels: newEnabled } });
  };

  const ocGroups = useMemo(() => {
    const groups: Record<string, { id: string; name: string }[]> = {};
    for (const m of openCodeModels) {
      const provider = m.provider ?? 'Other';
      if (!groups[provider]) groups[provider] = [];
      groups[provider].push({ id: m.id, name: m.name });
    }
    return Object.entries(groups)
      .sort(([a], [b]) => a.localeCompare(b))
      .map(([provider, models]) => ({ provider, models: models.sort((a, b) => a.name.localeCompare(b.name)) }));
  }, [openCodeModels]);

  const [addingProvider, setAddingProvider] = useState(false);
  const [selectedNewProvider, setSelectedNewProvider] = useState<string>('');
  const disabledProviders = ocGroups.filter((g) => !enabledProviders.includes(g.provider));

  const handleEnableProvider = async () => {
    if (!selectedNewProvider) return;
    await saveSettings({
      ...settings,
      ai: { ...settings.ai, enabledProviders: [...enabledProviders, selectedNewProvider] },
    });
    setAddingProvider(false);
    setSelectedNewProvider('');
  };

  const handleRemoveProvider = async (provider: string) => {
    await saveSettings({
      ...settings,
      ai: { ...settings.ai, enabledProviders: enabledProviders.filter((p) => p !== provider) },
    });
  };

  return (
    <Tabs value={subTab} onValueChange={setSubTab}>
      <TabsList className="w-full mb-4">
        <TabsTrigger value="opencode" className="flex-1 cursor-pointer">
          OpenCode
        </TabsTrigger>
        <TabsTrigger value="claude" className="flex-1 cursor-pointer">
          Claude
        </TabsTrigger>
      </TabsList>

      <TabsContent value="claude">
        <div className="grid gap-1">
          {claudeModels.map((m) => (
            <label
              key={m.id}
              className="flex items-center justify-between py-2 px-3 rounded-md hover:bg-duck-dark/5 cursor-pointer"
            >
              <span className="text-sm text-duck-dark">{m.name}</span>
              <Switch checked={enabledModels.includes(m.id)} onCheckedChange={() => toggleModel(m.id)} />
            </label>
          ))}
        </div>
      </TabsContent>

      <TabsContent value="opencode">
        <div className="flex justify-end items-center gap-2 mb-3">
          {addingProvider ? (
            <>
              <Select value={selectedNewProvider} onValueChange={setSelectedNewProvider}>
                <SelectTrigger className="h-9 flex-1 bg-white/60 border-duck-dark/20 text-duck-dark text-sm">
                  <SelectValue placeholder="Select provider..." />
                </SelectTrigger>
                <SelectContent className="z-[600]">
                  {disabledProviders.map((g) => (
                    <SelectItem key={g.provider} value={g.provider}>
                      {g.provider}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
              <Button
                type="button"
                size="sm"
                disabled={!selectedNewProvider}
                onClick={handleEnableProvider}
                className="cursor-pointer bg-duck-yellow hover:bg-duck-yellow/90 text-duck-teal font-bold disabled:opacity-50"
              >
                Enable
              </Button>
            </>
          ) : (
            <Button
              type="button"
              variant="outline"
              size="sm"
              className="cursor-pointer"
              onClick={() => setAddingProvider(true)}
              disabled={disabledProviders.length === 0}
            >
              Add Provider
            </Button>
          )}
        </div>
        {ocGroups.length === 0 ? (
          <p className="text-sm text-duck-dark/40">No OpenCode models available.</p>
        ) : (
          <OpenCodeProviderList
            groups={ocGroups}
            enabledProviders={enabledProviders}
            enabledModels={enabledModels}
            onToggleModel={toggleModel}
            onRemoveProvider={handleRemoveProvider}
          />
        )}
      </TabsContent>
    </Tabs>
  );
};

type ProviderGroup = { provider: string; models: { id: string; name: string }[] };

type OpenCodeProviderListProps = {
  groups: ProviderGroup[];
  enabledProviders: string[];
  enabledModels: string[];
  onToggleModel: (key: string) => void;
  onRemoveProvider: (provider: string) => void;
};

const OpenCodeProviderList = ({
  groups,
  enabledProviders,
  enabledModels,
  onToggleModel,
  onRemoveProvider,
}: OpenCodeProviderListProps) => {
  const [openProvider, setOpenProvider] = useUserState<string>('ai-settings-oc-accordion', '');
  const enabled = groups.filter((g) => enabledProviders.includes(g.provider));

  if (enabled.length === 0) {
    return <p className="text-sm text-duck-dark/40">No providers enabled.</p>;
  }

  return (
    <Accordion type="single" collapsible value={openProvider} onValueChange={(v) => setOpenProvider(v ?? '')}>
      {enabled.map((g) => (
        <AccordionItem key={g.provider} value={g.provider}>
          <AccordionTrigger className="py-2 px-3 text-sm font-medium text-duck-dark hover:no-underline [&>svg]:ml-1">
            <span className="flex-1 text-left">{g.provider}</span>
            <span className="text-xs opacity-60 mr-5">{g.models.length}</span>
            <button
              type="button"
              onClick={(ev) => {
                ev.stopPropagation();
                onRemoveProvider(g.provider);
              }}
              className="p-1 text-duck-dark/30 hover:text-red-500 cursor-pointer transition-colors mr-3"
            >
              <Trash2 className="h-3.5 w-3.5" />
            </button>
          </AccordionTrigger>
          <AccordionContent className="px-3 pb-2">
            <div className="grid gap-1 max-h-52 overflow-y-auto">
              {[...g.models]
                .sort((a, b) => {
                  const aEnabled = enabledModels.includes(`${g.provider}:${a.id}`);
                  const bEnabled = enabledModels.includes(`${g.provider}:${b.id}`);
                  if (aEnabled !== bEnabled) return aEnabled ? -1 : 1;
                  return a.name.localeCompare(b.name);
                })
                .map((m) => {
                  const key = `${g.provider}:${m.id}`;
                  return (
                    <label
                      key={m.id}
                      className="flex items-center justify-between py-1.5 px-2 rounded-md hover:bg-duck-dark/5 cursor-pointer"
                    >
                      <span className="text-sm text-duck-dark/70">{m.name}</span>
                      <Switch checked={enabledModels.includes(key)} onCheckedChange={() => onToggleModel(key)} />
                    </label>
                  );
                })}
            </div>
          </AccordionContent>
        </AccordionItem>
      ))}
    </Accordion>
  );
};
