"use client";

import React from "react";
import { useState, useMemo, useCallback, useRef } from "react";
import { useRouter } from "next/navigation";
import { useQueryClient } from "@tanstack/react-query";
import type { App, Message, FormatTemplate } from "@/lib/types";
import api, { streamCompletion } from "@/lib/api";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { Card, CardContent } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import { Sparkles, RotateCcw, Copy, Check, Loader2, FileText, ListChecks } from "lucide-react";
import { getCategoryIcon, getCategoryColor } from "@/lib/category-config";
import GovMarkdown from "@/components/ui/gov-markdown";
import { toast } from "sonner";
import ConversationSidebar from "./conversation-sidebar";

interface CompletionUIProps {
  app: App;
}

export default function CompletionUI({ app }: CompletionUIProps) {
  const router = useRouter();
  const queryClient = useQueryClient();
  const [input, setInput] = useState("");
  const [output, setOutput] = useState("");
  const [isLoading, setIsLoading] = useState(false);
  const [copied, setCopied] = useState(false);
  const [selectedFormat, setSelectedFormat] = useState<string>("");
  const [conversationId, setConversationId] = useState<string | undefined>();
  const abortRef = useRef<AbortController | null>(null);

  const handleNewConversation = useCallback(() => {
    setInput("");
    setOutput("");
    setSelectedFormat("");
    setConversationId(undefined);
  }, []);

  const handleSelectConversation = useCallback(
    async (convId: string) => {
      setConversationId(convId);
      try {
        const data = await api.get<{ data: Message[] }>(
          `/api/v1/apps/${app.id}/conversations/${convId}/messages`,
        );
        const msgs = data.data || [];
        const userMsg = msgs.find((m) => m.role === "user");
        const aiMsg = msgs.find((m) => m.role === "assistant");
        setInput(userMsg?.content || "");
        setOutput(aiMsg?.content || "");
      } catch {
        setInput("");
        setOutput("");
      }
    },
    [app.id],
  );

  const appConfig = useMemo(() => {
    try {
      if (typeof app.app_config === "string") return JSON.parse(app.app_config);
      return app.app_config || {};
    } catch {
      return {};
    }
  }, [app.app_config]);

  const inputLabel = appConfig.input_label || "输入内容";
  const inputPlaceholder = appConfig.input_placeholder || "在此输入...";
  const outputLabel = appConfig.output_label || "生成结果";
  const formatTemplates: Record<string, FormatTemplate> = appConfig.format_templates || {};
  const hasFormats = Object.keys(formatTemplates).length > 0;

  const CategoryIconComponent = getCategoryIcon(app.category_slug);
  const categoryColor = getCategoryColor(app.category_slug);

  const handleGenerate = useCallback(async () => {
    if (!input.trim() || isLoading) return;
    setIsLoading(true);
    setOutput("");

    const controller = new AbortController();
    abortRef.current = controller;

    let finalInput = input.trim();
    if (selectedFormat && formatTemplates[selectedFormat]) {
      const fmt = formatTemplates[selectedFormat];
      finalInput = `【输出格式要求】请按照「${fmt.name}」格式生成，包含以下章节：${fmt.sections.join("、")}。\n\n${finalInput}`;
    }

    try {
      const res = await streamCompletion(app.id, finalInput, controller.signal);
      if (!res.ok) throw new Error("请求失败");
      const reader = res.body?.getReader();
      const decoder = new TextDecoder();
      if (!reader) throw new Error("无法获取响应流");

      let buffer = "";
      let accumulated = "";
      while (true) {
        const { done, value } = await reader.read();
        if (done) break;
        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split("\n");
        buffer = lines.pop() || "";
        for (const line of lines) {
          if (!line.startsWith("data: ")) continue;
          const raw = line.slice(6);
          if (raw === "[DONE]") break;
          try {
            const event = JSON.parse(raw);
            if (event.conversation_id) setConversationId(event.conversation_id);
            if (event.answer) {
              accumulated += event.answer;
              setOutput(accumulated);
            }
          } catch {
            /* skip */
          }
        }
      }
      queryClient.invalidateQueries({ queryKey: ["conversations", app.id] });
      // 延迟刷新以获取LLM生成的对话名称
      setTimeout(() => {
        queryClient.invalidateQueries({ queryKey: ["conversations", app.id] });
      }, 3000);
    } catch (err) {
      if ((err as Error).name === "AbortError") return;
      toast.error("生成失败，请重试");
    } finally {
      abortRef.current = null;
      setIsLoading(false);
    }
  }, [input, isLoading, app.id, selectedFormat, formatTemplates, queryClient]);

  const handleCopy = useCallback(async () => {
    await navigator.clipboard.writeText(output);
    setCopied(true);
    toast.success("已复制到剪贴板");
    setTimeout(() => setCopied(false), 2000);
  }, [output]);

  const handleReset = useCallback(() => {
    if (abortRef.current) abortRef.current.abort();
    setInput("");
    setOutput("");
    setSelectedFormat("");
  }, []);

  return (
    <div className="flex h-[calc(100vh-3.5rem)] overflow-hidden">
      <ConversationSidebar
        appId={app.id}
        currentConvId={conversationId}
        onSelectConversation={handleSelectConversation}
        onNewConversation={handleNewConversation}
      />

      <div className="flex-1 flex flex-col min-w-0 overflow-hidden">
        <div className="border-b px-3 md:px-5 py-3 flex items-center gap-2 md:gap-3 shrink-0">
          <div
            className={`flex h-8 w-8 items-center justify-center rounded-lg ${categoryColor} shrink-0`}
          >
            {CategoryIconComponent
              ? React.createElement(CategoryIconComponent, { className: "h-4 w-4" })
              : null}
          </div>
          <div className="min-w-0">
            <h1 className="font-semibold text-sm truncate">{app.name}</h1>
            <p className="text-xs text-muted-foreground truncate">{app.description}</p>
          </div>
          <div className="ml-auto flex items-center gap-1.5 text-xs text-blue-800 bg-blue-100 px-2 py-1 rounded-full font-medium">
            <FileText className="h-3 w-3" />
            <span className="hidden sm:inline">补全型</span>
          </div>
        </div>

        <div className="flex-1 overflow-auto">
          <div className="mx-auto w-full max-w-7xl px-3 md:px-6 lg:px-8 py-4 md:py-6 space-y-4 md:space-y-6">
            {/* 格式选择区域 */}
            {hasFormats && (
              <Card>
                <CardContent className="p-4">
                  <div className="flex items-center gap-2 mb-3">
                    <ListChecks className="h-4 w-4 text-muted-foreground" />
                    <label className="text-sm font-medium">选择输出格式</label>
                  </div>
                  <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-2">
                    {Object.entries(formatTemplates).map(([key, fmt]) => (
                      <button
                        key={key}
                        onClick={() => setSelectedFormat(selectedFormat === key ? "" : key)}
                        className={`text-left p-3 rounded-lg border transition-all ${
                          selectedFormat === key
                            ? "border-emerald-500 bg-emerald-50 ring-1 ring-emerald-500"
                            : "border-border hover:border-emerald-300 hover:bg-emerald-50/50"
                        }`}
                      >
                        <div className="text-sm font-medium truncate">{fmt.name}</div>
                        <div className="text-xs text-muted-foreground mt-0.5 line-clamp-2">
                          {fmt.description}
                        </div>
                      </button>
                    ))}
                  </div>
                  {selectedFormat && formatTemplates[selectedFormat] && (
                    <div className="mt-3 p-2.5 rounded-md bg-emerald-50 border border-emerald-200/60">
                      <p className="text-xs text-emerald-700">
                        <span className="font-medium">包含章节：</span>
                        {formatTemplates[selectedFormat].sections.join(" → ")}
                      </p>
                    </div>
                  )}
                </CardContent>
              </Card>
            )}

            <Card>
              <CardContent className="p-5 space-y-3">
                <label className="text-sm font-medium">{inputLabel}</label>
                <Textarea
                  value={input}
                  onChange={(e) => setInput(e.target.value)}
                  placeholder={inputPlaceholder}
                  className="min-h-[160px] resize-none"
                  disabled={isLoading}
                />
                <div className="flex items-center gap-2">
                  <Button
                    onClick={handleGenerate}
                    disabled={!input.trim() || isLoading}
                    className="gap-2"
                  >
                    {isLoading ? (
                      <Loader2 className="h-4 w-4 animate-spin" />
                    ) : (
                      <Sparkles className="h-4 w-4" />
                    )}
                    {isLoading ? "生成中..." : "生成"}
                  </Button>
                  {selectedFormat && formatTemplates[selectedFormat] && (
                    <span className="text-xs text-emerald-600 bg-emerald-50 px-2 py-1 rounded">
                      格式：{formatTemplates[selectedFormat].name}
                    </span>
                  )}
                  {(output || input) && (
                    <Button variant="outline" onClick={handleReset} className="gap-2">
                      <RotateCcw className="h-4 w-4" />
                      重置
                    </Button>
                  )}
                </div>
              </CardContent>
            </Card>

            {isLoading && !output && (
              <Card>
                <CardContent className="p-5 space-y-3">
                  <Skeleton className="h-4 w-24" />
                  <Skeleton className="h-4 w-full" />
                  <Skeleton className="h-4 w-full" />
                  <Skeleton className="h-4 w-3/4" />
                </CardContent>
              </Card>
            )}

            {output && (
              <Card className="border-emerald-200/60 bg-emerald-50/30">
                <CardContent className="p-5">
                  <div className="flex items-center justify-between mb-3">
                    <label className="text-sm font-medium text-emerald-800">{outputLabel}</label>
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={handleCopy}
                      className="gap-1.5 text-xs h-7"
                    >
                      {copied ? <Check className="h-3 w-3" /> : <Copy className="h-3 w-3" />}
                      {copied ? "已复制" : "复制"}
                    </Button>
                  </div>
                  <GovMarkdown content={output} />
                </CardContent>
              </Card>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}
