"use client";

import * as React from "react";
import Link from "next/link";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { apiFetch } from "@/lib/api";
import type { ChatRecord } from "@/components/chat/chat-view";
import type { OllamaModelInfo } from "@/lib/ollama";
import { Button } from "@/components/ui/button";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import { Slider } from "@/components/ui/slider";
import { Switch } from "@/components/ui/switch";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { CONTEXT_PRESETS, DEFAULT_SYSTEM_PROMPT, KEEP_ALIVE_PRESETS } from "@/lib/constants";
import { PanelLeft, Settings2, RotateCcw, Settings as SettingsIcon, Brain, Wrench } from "lucide-react";
import { useUIStore } from "@/lib/stores/ui-store";
import { ThemeToggle } from "@/components/theme-toggle";
import { toast } from "sonner";

export function ChatHeader({ chat }: { chat: ChatRecord }) {
  const toggleSidebar = useUIStore((s) => s.toggleSidebar);
  const showQuery = useQuery({
    queryKey: ["model-show", chat.model],
    queryFn: () =>
      apiFetch<{ capabilities: string[]; supportsThinking: boolean; supportsTools: boolean }>(
        `/api/models/show?name=${encodeURIComponent(chat.model)}`,
      ),
    enabled: !!chat.model,
    staleTime: Infinity,
    retry: false,
  });
  const canThink = !!showQuery.data?.supportsThinking;
  const canTools = !!showQuery.data?.supportsTools;

  return (
    <header className="flex h-14 shrink-0 items-center justify-between border-b border-border px-4">
      <div className="flex min-w-0 items-center gap-2">
        <Button variant="ghost" size="icon-sm" onClick={toggleSidebar} aria-label="Toggle sidebar">
          <PanelLeft />
        </Button>
        <span className="truncate font-serif text-base">{chat.title}</span>
        <span className="ml-2 hidden truncate rounded-full bg-muted px-2 py-0.5 text-[11px] text-muted-foreground sm:inline">
          {chat.model}
        </span>
        {canThink && (
          <span className="hidden items-center gap-1 rounded-full bg-primary/10 px-2 py-0.5 text-[10px] font-medium text-primary sm:inline-flex">
            <Brain className="h-2.5 w-2.5" />
            thinks
          </span>
        )}
        {canTools && (
          <span className="hidden items-center gap-1 rounded-full bg-emerald-500/10 px-2 py-0.5 text-[10px] font-medium text-emerald-600 dark:text-emerald-400 sm:inline-flex">
            <Wrench className="h-2.5 w-2.5" />
            tools
          </span>
        )}
      </div>
      <div className="flex items-center gap-1">
        <ChatConfigPopover chat={chat} />
        <ThemeToggle />
        <Button asChild variant="ghost" size="icon-sm" aria-label="Settings">
          <Link href="/settings">
            <SettingsIcon />
          </Link>
        </Button>
      </div>
    </header>
  );
}

function ChatConfigPopover({ chat }: { chat: ChatRecord }) {
  const qc = useQueryClient();
  const modelsQuery = useQuery({
    queryKey: ["models"],
    queryFn: () => apiFetch<{ models: OllamaModelInfo[] }>("/api/models"),
    retry: false,
  });

  const [model, setModel] = React.useState(chat.model);
  const showQuery = useQuery({
    queryKey: ["model-show", model],
    queryFn: () =>
      apiFetch<{ capabilities: string[]; supportsThinking: boolean }>(
        `/api/models/show?name=${encodeURIComponent(model)}`,
      ),
    enabled: !!model,
    staleTime: Infinity,
    retry: false,
  });
  const canThink = !!showQuery.data?.supportsThinking;

  const [contextWindow, setContextWindow] = React.useState(chat.contextWindow);
  const [contextMode, setContextMode] = React.useState<"preset" | "custom">(
    CONTEXT_PRESETS.some((p) => p.value === chat.contextWindow) ? "preset" : "custom",
  );
  const [keepAlive, setKeepAlive] = React.useState(chat.keepAlive);
  const [keepAliveMode, setKeepAliveMode] = React.useState<"preset" | "custom">(
    KEEP_ALIVE_PRESETS.some((p) => p.value === chat.keepAlive) ? "preset" : "custom",
  );
  const [systemPrompt, setSystemPrompt] = React.useState(chat.systemPrompt);
  const [temperature, setTemperature] = React.useState(chat.temperature);
  const [showThinking, setShowThinking] = React.useState(chat.showThinking);

  React.useEffect(() => {
    setModel(chat.model);
    setContextWindow(chat.contextWindow);
    setKeepAlive(chat.keepAlive);
    setSystemPrompt(chat.systemPrompt);
    setTemperature(chat.temperature);
    setShowThinking(chat.showThinking);
  }, [
    chat.id,
    chat.model,
    chat.contextWindow,
    chat.keepAlive,
    chat.systemPrompt,
    chat.temperature,
    chat.showThinking,
  ]);

  const save = useMutation({
    mutationFn: () =>
      apiFetch(`/api/chats/${chat.id}`, {
        method: "PATCH",
        body: JSON.stringify({
          model,
          contextWindow,
          keepAlive,
          systemPrompt,
          temperature,
          showThinking,
        }),
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["chat", chat.id] });
      qc.invalidateQueries({ queryKey: ["chats"] });
      toast.success("Chat settings saved");
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const models = modelsQuery.data?.models ?? [];

  return (
    <Popover>
      <PopoverTrigger asChild>
        <Button variant="ghost" size="icon-sm" aria-label="Chat settings">
          <Settings2 />
        </Button>
      </PopoverTrigger>
      <PopoverContent align="end" className="w-[22rem]">
        <div className="space-y-4">
          <div className="space-y-1.5">
            <Label className="text-xs">Model</Label>
            <Select value={model} onValueChange={setModel}>
              <SelectTrigger className="h-8 text-xs">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {models.length === 0 && (
                  <SelectItem value={chat.model}>{chat.model}</SelectItem>
                )}
                {models.map((m) => (
                  <SelectItem key={m.name} value={m.name}>
                    {m.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="space-y-1.5">
            <Label className="text-xs">Context window</Label>
            <Select
              value={contextMode === "preset" ? String(contextWindow) : "custom"}
              onValueChange={(v) => {
                if (v === "custom") {
                  setContextMode("custom");
                } else {
                  setContextMode("preset");
                  setContextWindow(Number(v));
                }
              }}
            >
              <SelectTrigger className="h-8 text-xs">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {CONTEXT_PRESETS.map((p) => (
                  <SelectItem key={p.value} value={String(p.value)}>
                    {p.label} ({p.value.toLocaleString()})
                  </SelectItem>
                ))}
                <SelectItem value="custom">Custom…</SelectItem>
              </SelectContent>
            </Select>
            {contextMode === "custom" && (
              <Input
                type="number"
                min={512}
                step={512}
                value={contextWindow}
                onChange={(e) => setContextWindow(Number(e.target.value))}
                className="mt-2 h-8 text-xs"
              />
            )}
          </div>

          <div className="space-y-1.5">
            <Label className="text-xs">Keep alive</Label>
            <Select
              value={keepAliveMode === "preset" ? String(keepAlive) : "custom"}
              onValueChange={(v) => {
                if (v === "custom") {
                  setKeepAliveMode("custom");
                } else {
                  setKeepAliveMode("preset");
                  setKeepAlive(Number(v));
                }
              }}
            >
              <SelectTrigger className="h-8 text-xs">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {KEEP_ALIVE_PRESETS.map((p) => (
                  <SelectItem key={p.value} value={String(p.value)}>
                    {p.label}
                  </SelectItem>
                ))}
                <SelectItem value="custom">Custom…</SelectItem>
              </SelectContent>
            </Select>
            {keepAliveMode === "custom" && (
              <Input
                type="number"
                min={-1}
                value={keepAlive}
                onChange={(e) => setKeepAlive(Number(e.target.value))}
                className="mt-2 h-8 text-xs"
                placeholder="Seconds (-1 = forever)"
              />
            )}
          </div>

          <div className="space-y-1.5">
            <div className="flex items-center justify-between">
              <Label className="text-xs">System prompt</Label>
              <Button
                variant="ghost"
                size="sm"
                className="h-6 px-2 text-[11px]"
                onClick={() => setSystemPrompt(DEFAULT_SYSTEM_PROMPT)}
              >
                <RotateCcw className="!h-3 !w-3" />
                Reset
              </Button>
            </div>
            <Textarea
              value={systemPrompt}
              onChange={(e) => setSystemPrompt(e.target.value)}
              className="min-h-[100px] text-xs"
              placeholder="Optional instructions for the assistant…"
            />
          </div>

          <div className="space-y-1.5">
            <div className="flex items-center justify-between">
              <Label className="text-xs">Temperature</Label>
              <span className="font-mono text-xs text-muted-foreground">{temperature.toFixed(2)}</span>
            </div>
            <Slider
              min={0}
              max={2}
              step={0.05}
              value={[temperature]}
              onValueChange={(v) => setTemperature(v[0] ?? 0)}
            />
          </div>

          <div className="flex items-center justify-between rounded-lg border border-border px-3 py-2">
            <div>
              <Label className="text-xs">Show thinking</Label>
              <p className="text-[11px] text-muted-foreground">
                {canThink
                  ? "Display reasoning blocks"
                  : "This model doesn't support thinking"}
              </p>
            </div>
            <Switch
              checked={canThink && showThinking}
              onCheckedChange={setShowThinking}
              disabled={!canThink}
            />
          </div>

          <Button onClick={() => save.mutate()} disabled={save.isPending} className="w-full" size="sm">
            {save.isPending ? "Saving…" : "Save"}
          </Button>
        </div>
      </PopoverContent>
    </Popover>
  );
}
