import { memo, useState, useEffect, useCallback } from 'react';
import type { RoomResponse } from '@/client';
import { aiList, aiUpsert, aiDelete, modelList } from '@/client';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/dialog';
import { Loader2, Plus, Trash2, Bot, ChevronDown, ChevronRight } from 'lucide-react';
import { toast } from 'sonner';
import type { ModelResponse, RoomAiResponse, RoomAiUpsertRequest } from '@/client';

interface RoomSettingsPanelProps {
  room: RoomResponse;
  onUpdate: (name: string, isPublic: boolean) => Promise<void>;
  onClose: () => void;
  isPending: boolean;
}

export const RoomSettingsPanel = memo(function RoomSettingsPanel({
  room,
  onUpdate,
  onClose,
  isPending,
}: RoomSettingsPanelProps) {
  const [name, setName] = useState(room.room_name ?? '');
  const [isPublic, setIsPublic] = useState(!!room.public);

  // AI section state
  const [aiConfigs, setAiConfigs] = useState<RoomAiResponse[]>([]);
  const [aiConfigsLoading, setAiConfigsLoading] = useState(false);
  const [showAiAddDialog, setShowAiAddDialog] = useState(false);
  const [showAdvanced, setShowAdvanced] = useState(false);

  // Add AI form state
  const [availableModels, setAvailableModels] = useState<ModelResponse[]>([]);
  const [modelsLoading, setModelsLoading] = useState(false);
  const [selectedModelId, setSelectedModelId] = useState('');
  const [temperature, setTemperature] = useState('');
  const [maxTokens, setMaxTokens] = useState('');
  const [historyLimit, setHistoryLimit] = useState('');
  const [systemPrompt, setSystemPrompt] = useState('');
  const [useExact, setUseExact] = useState(false);
  const [think, setThink] = useState(false);
  const [stream, setStream] = useState(true);
  const [isAddingAi, setIsAddingAi] = useState(false);

  const handleSave = async () => {
    if (!name.trim()) return;
    try {
      await onUpdate(name.trim(), isPublic);
      toast.success('Room updated');
      onClose();
    } catch {
      toast.error('Failed to update room');
    }
  };

  // Load AI configs
  const loadAiConfigs = useCallback(async () => {
    setAiConfigsLoading(true);
    try {
      const resp = await aiList({ path: { room_id: room.id } });
      const inner = (resp.data as Record<string, unknown>)?.['200'] as Record<string, unknown> | undefined;
      setAiConfigs(Array.isArray(inner?.['data']) ? (inner['data'] as RoomAiResponse[]) : []);
    } catch {
      // ignore
    } finally {
      setAiConfigsLoading(false);
    }
  }, [room.id]);

  useEffect(() => {
    loadAiConfigs();
  }, [loadAiConfigs]);

  // Load available models
  const loadModels = useCallback(async () => {
    setModelsLoading(true);
    try {
      const resp = await modelList({});
      const raw = resp.data as Record<string, unknown> | undefined;
      setAvailableModels(Array.isArray(raw?.['200']) ? (raw['200'] as ModelResponse[]) : []);
    } catch {
      toast.error('Failed to load models');
    } finally {
      setModelsLoading(false);
    }
  }, []);

  const openAddDialog = () => {
    setSelectedModelId('');
    setTemperature('');
    setMaxTokens('');
    setHistoryLimit('');
    setSystemPrompt('');
    setUseExact(false);
    setThink(false);
    setStream(true);
    setShowAdvanced(false);
    setShowAiAddDialog(true);
    loadModels();
  };

  const handleAddAi = async () => {
    if (!selectedModelId) {
      toast.error('Please select a model');
      return;
    }
    setIsAddingAi(true);
    try {
      const body: RoomAiUpsertRequest = {
        model: selectedModelId,
        temperature: temperature ? parseFloat(temperature) : undefined,
        max_tokens: maxTokens ? parseInt(maxTokens) : undefined,
        history_limit: historyLimit ? parseInt(historyLimit) : undefined,
        system_prompt: systemPrompt || undefined,
        use_exact: useExact,
        think,
        stream,
      };
      await aiUpsert({
        path: { room_id: room.id },
        body,
      });
      toast.success('AI model added');
      setShowAiAddDialog(false);
      loadAiConfigs();
    } catch {
      toast.error('Failed to add AI model');
    } finally {
      setIsAddingAi(false);
    }
  };

  const handleDeleteAi = async (modelId: string) => {
    try {
      await aiDelete({ path: { room_id: room.id, model_id: modelId } });
      toast.success('AI model removed');
      setAiConfigs((prev) => prev.filter((c) => c.model !== modelId));
    } catch {
      toast.error('Failed to remove AI model');
    }
  };

  return (
    <aside className="hidden w-[380px] border-l border-border/70 bg-card/50 xl:flex xl:flex-col">
      <header className="flex h-12 items-center border-b border-border/70 px-3">
        <p className="text-sm font-semibold text-foreground">Room Settings</p>
      </header>

      <div className="flex-1 overflow-y-auto p-4 space-y-6">
        {/* General Section */}
        <section className="space-y-3">
          <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">General</h3>

          <div className="space-y-2">
            <Label className="text-sm">Room name</Label>
            <Input
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="Room name"
            />
          </div>

          <div className="flex items-center justify-between">
            <div>
              <p className="text-sm font-medium">Public</p>
              <p className="text-xs text-muted-foreground">Visible to all project members</p>
            </div>
            <Switch
              checked={isPublic}
              onCheckedChange={setIsPublic}
              aria-label="Public room visibility"
            />
          </div>

          <Button onClick={handleSave} disabled={!name.trim() || isPending} className="w-full">
            {isPending ? (
              <Loader2 className="mr-2 h-4 w-4 animate-spin" />
            ) : null}
            Save Changes
          </Button>
        </section>

        {/* AI Section */}
        <section className="space-y-3">
          <div className="flex items-center justify-between">
            <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">AI Models</h3>
            <Button variant="ghost" size="sm" className="h-7 gap-1 px-2" onClick={openAddDialog}>
              <Plus className="h-3 w-3" />
              Add
            </Button>
          </div>

          {aiConfigsLoading ? (
            <div className="flex justify-center py-4">
              <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
            </div>
          ) : aiConfigs.length === 0 ? (
            <p className="text-xs text-muted-foreground py-2">No AI models configured</p>
          ) : (
            <div className="space-y-2">
              {aiConfigs.map((config) => (
                <div
                  key={config.model}
                  className="flex items-center justify-between rounded-md border border-border/70 bg-muted/30 px-3 py-2"
                >
                  <div className="flex items-center gap-2 min-w-0">
                    <Bot className="h-4 w-4 text-muted-foreground shrink-0" />
                    <span className="text-sm truncate font-mono text-foreground">
                      {config.model}
                    </span>
                    {config.stream && (
                      <span className="rounded bg-green-500/10 px-1 py-0.5 text-[10px] text-green-600 dark:text-green-400 shrink-0">
                        streaming
                      </span>
                    )}
                    {config.think && (
                      <span className="rounded bg-blue-500/10 px-1 py-0.5 text-[10px] text-blue-600 dark:text-blue-400 shrink-0">
                        think
                      </span>
                    )}
                  </div>
                  <Button
                    variant="ghost"
                    size="icon"
                    className="h-7 w-7 text-muted-foreground hover:text-destructive shrink-0"
                    onClick={() => handleDeleteAi(config.model)}
                  >
                    <Trash2 className="h-3.5 w-3.5" />
                  </Button>
                </div>
              ))}
            </div>
          )}
        </section>
      </div>

      {/* Add AI Dialog */}
      <Dialog open={showAiAddDialog} onOpenChange={setShowAiAddDialog}>
        <DialogContent className="sm:max-w-[440px]">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <Bot className="h-4 w-4" />
              Add AI Model
            </DialogTitle>
          </DialogHeader>

          <div className="space-y-4 py-2">
            {/* Model selection */}
            <div className="space-y-2">
              <Label className="text-sm">Model</Label>
              {modelsLoading ? (
                <div className="flex items-center gap-2 h-8 px-3 rounded-md border border-input bg-muted/30 text-sm text-muted-foreground">
                  <Loader2 className="h-4 w-4 animate-spin" />
                  Loading models...
                </div>
              ) : (
                <Select value={selectedModelId} onValueChange={(v) => { if (v !== null) setSelectedModelId(v); }}>
                  <SelectTrigger className="w-full">
                    <SelectValue placeholder="Select a model..." />
                  </SelectTrigger>
                  <SelectContent>
                    {availableModels.map((model) => (
                      <SelectItem key={model.id} value={model.id}>
                        <div className="flex flex-col items-start gap-0.5">
                          <span className="font-medium">{model.name}</span>
                          <span className="text-xs text-muted-foreground">
                            {model.capability} · {model.modality}
                          </span>
                        </div>
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              )}
            </div>

            {/* System prompt */}
            <div className="space-y-2">
              <Label className="text-sm">System Prompt</Label>
              <textarea
                className="min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm resize-none focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
                placeholder="Optional system prompt for this AI..."
                value={systemPrompt}
                onChange={(e) => setSystemPrompt(e.target.value)}
              />
            </div>

            {/* Advanced settings toggle */}
            <button
              type="button"
              className="flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors"
              onClick={() => setShowAdvanced((v) => !v)}
            >
              {showAdvanced ? <ChevronDown className="h-3 w-3" /> : <ChevronRight className="h-3 w-3" />}
              Advanced options
            </button>

            {showAdvanced && (
              <div className="space-y-3 pl-1">
                {/* Temperature */}
                <div className="space-y-1">
                  <Label className="text-xs">Temperature</Label>
                  <Input
                    type="number"
                    step="0.1"
                    min="0"
                    max="2"
                    placeholder="e.g. 0.7"
                    value={temperature}
                    onChange={(e) => setTemperature(e.target.value)}
                  />
                </div>

                {/* Max tokens */}
                <div className="space-y-1">
                  <Label className="text-xs">Max Tokens</Label>
                  <Input
                    type="number"
                    placeholder="e.g. 4096"
                    value={maxTokens}
                    onChange={(e) => setMaxTokens(e.target.value)}
                  />
                </div>

                {/* History limit */}
                <div className="space-y-1">
                  <Label className="text-xs">History Limit (messages)</Label>
                  <Input
                    type="number"
                    placeholder="e.g. 50"
                    value={historyLimit}
                    onChange={(e) => setHistoryLimit(e.target.value)}
                  />
                </div>

                {/* Toggles */}
                <div className="space-y-2">
                  <div className="flex items-center justify-between">
                    <Label className="text-xs">Use Exact</Label>
                    <Switch checked={useExact} onCheckedChange={setUseExact} size="sm" />
                  </div>
                  <div className="flex items-center justify-between">
                    <Label className="text-xs">Think Mode</Label>
                    <Switch checked={think} onCheckedChange={setThink} size="sm" />
                  </div>
                  <div className="flex items-center justify-between">
                    <Label className="text-xs">Streaming</Label>
                    <Switch checked={stream} onCheckedChange={setStream} size="sm" />
                  </div>
                </div>
              </div>
            )}
          </div>

          <DialogFooter>
            <Button variant="outline" onClick={() => setShowAiAddDialog(false)}>
              Cancel
            </Button>
            <Button onClick={handleAddAi} disabled={!selectedModelId || isAddingAi}>
              {isAddingAi ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : null}
              Add Model
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </aside>
  );
});
