"use client";

import { useState, useRef, useEffect, useCallback } from "react";
import { useTheme } from "next-themes";
import { useSearchParams } from "next/navigation";
import { fetchAPI, type DiagnosisResult } from "@/lib/api";
import { markdownToHtml } from "@/lib/markdown";
import { ErrorBoundary } from "@/components/error-boundary";

interface SearchResult {
  ts_code: string;
  name: string;
  industry: string;
}

export default function DiagnosePage() {
  const { theme } = useTheme();
  const searchParams = useSearchParams();
  const codeParam = searchParams.get("code");
  const [input, setInput] = useState("");
  const [searchResults, setSearchResults] = useState<SearchResult[]>([]);
  const [showSearch, setShowSearch] = useState(false);
  const [loading, setLoading] = useState(false);
  const [streamingContent, setStreamingContent] = useState("");
  const [result, setResult] = useState<DiagnosisResult | null>(null);
  const [cachedResult, setCachedResult] = useState<string | null>(null);
  const [history, setHistory] = useState<{ ts_code: string; name: string }[]>([]);
  const inputRef = useRef<HTMLInputElement>(null);
  const searchTimer = useRef<ReturnType<typeof setTimeout>>();
  const wrapperRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    function handleClick(e: MouseEvent) {
      if (wrapperRef.current && !wrapperRef.current.contains(e.target as Node)) {
        setShowSearch(false);
      }
    }
    document.addEventListener("mousedown", handleClick);
    return () => document.removeEventListener("mousedown", handleClick);
  }, []);

  useEffect(() => {
    if (!codeParam) return;
    setInput(codeParam);
    runDiagnosis(codeParam);
  }, [codeParam]);

  const searchStock = useCallback(async (keyword: string) => {
    if (!keyword.trim() || keyword.length < 1) {
      setSearchResults([]);
      setShowSearch(false);
      return;
    }
    try {
      const data = await fetchAPI<SearchResult[]>(`/api/stocks/search?keyword=${encodeURIComponent(keyword)}`);
      setSearchResults(data);
      setShowSearch(data.length > 0);
    } catch {
      setSearchResults([]);
    }
  }, []);

  const handleInputChange = (value: string) => {
    setInput(value);
    clearTimeout(searchTimer.current);
    searchTimer.current = setTimeout(() => searchStock(value), 300);
  };

  const selectStock = (stock: SearchResult) => {
    setInput(`${stock.name} (${stock.ts_code})`);
    setShowSearch(false);
    setSearchResults([]);
  };

  const runDiagnosis = async (tsCode?: string) => {
    let code = tsCode;
    if (!code) {
      const match = input.match(/\((\d{6}\.[A-Z]{2})\)/);
      if (match) {
        code = match[1];
      } else if (/^\d{6}$/.test(input.trim())) {
        code = `${input.trim()}.SH`;
      } else if (/^\d{6}\.[A-Z]{2}$/.test(input.trim())) {
        code = input.trim();
      }
    }

    if (!code) return;

    setLoading(true);
    setStreamingContent("");
    setResult(null);
    setCachedResult(null);

    try {
      const token = localStorage.getItem("auth_token");
      const headers: Record<string, string> = {};
      if (token) headers["Authorization"] = `Bearer ${token}`;

      const res = await fetch(`/api/stocks/${code}/diagnose`, {
        method: "POST",
        headers,
      });

      if (!res.ok) throw new Error(`API error: ${res.status}`);
      if (!res.body) throw new Error("No response body");

      const reader = res.body.getReader();
      const decoder = new TextDecoder();
      let buffer = "";
      let fullContent = "";

      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: ")) {
            const data = line.slice(6).trim();
            try {
              const parsed = JSON.parse(data);

              if (parsed.cached && parsed.diagnosis) {
                setCachedResult(parsed.diagnosis);
                fullContent = parsed.diagnosis;
              } else if (parsed.token) {
                fullContent += parsed.token;
                setStreamingContent(fullContent);
              } else if (parsed.error) {
                setResult({ status: "error", message: parsed.error });
              } else if (parsed.done) {
                if (fullContent) {
                  setResult({ status: "ok", ts_code: parsed.ts_code || code, diagnosis: fullContent });
                  const name = input.split(" (")[0] || parsed.ts_code || code;
                  setHistory((prev) => {
                    const filtered = prev.filter((h) => h.ts_code !== (parsed.ts_code || code));
                    return [{ ts_code: parsed.ts_code || code, name }, ...filtered].slice(0, 10);
                  });
                }
              }
            } catch {
              // ignore malformed lines
            }
          }
        }
      }
    } catch (e) {
      setResult({ status: "error", message: "诊断失败，请检查股票代码后重试" });
    } finally {
      setLoading(false);
    }
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === "Enter" && !showSearch) {
      e.preventDefault();
      runDiagnosis();
    }
  };

  const displayContent = cachedResult || result?.diagnosis || streamingContent;

  return (
    <ErrorBoundary>
    <div className="max-w-3xl mx-auto px-4 md:px-8 pt-6 pb-20 md:pb-10">
      {/* Header */}
      <div className="mb-6 animate-fade-in-up">
        <div className="flex items-center gap-3 mb-1">
          <div className="w-8 h-8 rounded-xl bg-gradient-to-br from-amber-500/25 to-amber-600/15 flex items-center justify-center border border-amber-500/15">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" className="text-amber-400">
              <path d="M9 11l3 3L22 4" />
              <path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11" />
            </svg>
          </div>
          <div>
            <h1 className="text-lg font-bold tracking-tight">AI 诊断</h1>
            <p className="text-xs text-text-muted">
              输入任意股票代码，AI 综合技术面、资金面进行全面分析
            </p>
          </div>
        </div>
      </div>

      {/* Search Input */}
      <div ref={wrapperRef} className="relative z-30 mb-6 animate-fade-in-up">
        <div className="flex gap-2">
          <div className="relative flex-1">
            <input
              ref={inputRef}
              type="text"
              value={input}
              onChange={(e) => handleInputChange(e.target.value)}
              onKeyDown={handleKeyDown}
              onFocus={() => searchResults.length > 0 && setShowSearch(true)}
              placeholder="输入股票名称或代码，如 600683 或 京投发展"
              className="w-full bg-surface-2 rounded-xl px-4 py-3 text-sm focus:outline-none focus:ring-1 focus:ring-amber-400/30 placeholder-text-muted/40 border border-border-subtle transition-all duration-200"
              disabled={loading}
            />
          </div>
          <button
            onClick={() => runDiagnosis()}
            disabled={loading || !input.trim()}
            className="px-6 py-3 bg-gradient-to-r from-amber-500/20 to-amber-600/15 text-amber-400 rounded-xl text-sm font-medium hover:from-amber-500/30 hover:to-amber-600/25 disabled:opacity-30 transition-all duration-200 border border-amber-500/10 shrink-0"
          >
            {loading ? (
              <span className="inline-flex items-center gap-1.5">
                <span className="w-3.5 h-3.5 border border-amber-400/40 border-t-amber-400 rounded-full animate-spin" />
                分析中
              </span>
            ) : (
              "开始诊断"
            )}
          </button>
        </div>
        {showSearch && searchResults.length > 0 && (
          <div className="absolute top-full left-0 right-0 mt-1 bg-bg-secondary border border-border-subtle rounded-xl shadow-lg z-20 overflow-hidden">
            {searchResults.map((stock) => (
              <button
                key={stock.ts_code}
                onClick={() => selectStock(stock)}
                className="w-full flex items-center justify-between px-4 py-2.5 text-sm hover:bg-surface-3 transition-colors text-left"
              >
                <div className="flex items-center gap-2">
                  <span className="text-text-primary font-medium">{stock.name}</span>
                  <span className="text-text-muted text-xs">{stock.ts_code}</span>
                </div>
                {stock.industry && (
                  <span className="text-[10px] px-1.5 py-0.5 rounded bg-surface-2 text-text-muted">
                    {stock.industry}
                  </span>
                )}
              </button>
            ))}
          </div>
        )}
      </div>

      {/* History */}
      {history.length > 0 && !displayContent && (
        <div className="mb-6 animate-fade-in-up">
          <div className="text-[10px] text-text-muted/50 mb-2 uppercase tracking-wider">最近诊断</div>
          <div className="flex flex-wrap gap-2">
            {history.map((h) => (
              <button
                key={h.ts_code}
                onClick={() => {
                  setInput(`${h.name} (${h.ts_code})`);
                  runDiagnosis(h.ts_code);
                }}
                className="text-xs px-3 py-1.5 bg-surface-2 rounded-lg text-text-secondary hover:text-text-primary hover:bg-surface-3 transition-all border border-border-subtle"
              >
                {h.name}
                <span className="text-text-muted/50 ml-1">{h.ts_code}</span>
              </button>
            ))}
          </div>
        </div>
      )}

      {/* Streaming / Loading State */}
      {loading && !displayContent && (
        <div className="glass-card-static p-10 text-center animate-fade-in-up">
          <div className="w-8 h-8 border-2 border-amber-400/30 border-t-amber-400 rounded-full animate-spin mx-auto mb-3" />
          <div className="text-sm text-text-secondary mb-1">正在分析中...</div>
          <div className="text-xs text-text-muted/50">收集行情数据、技术指标、资金流向并生成分析报告</div>
        </div>
      )}

      {/* Streaming content */}
      {loading && displayContent && (
        <div className="glass-card-static p-5 animate-fade-in-up">
          <div className="flex items-center gap-2 mb-3">
            <span className="w-3 h-3 border border-amber-400/40 border-t-amber-400 rounded-full animate-spin" />
            <span className="text-xs text-text-muted">AI 正在分析...</span>
          </div>
          <div className="text-sm text-text-secondary leading-relaxed whitespace-pre-line">
            {displayContent}
          </div>
        </div>
      )}

      {/* Final Result */}
      {!loading && displayContent && (
        <div className="animate-fade-in-up">
          <div className="glass-card-static p-5">
            <div className="flex items-center justify-between mb-4">
              <div className="flex items-center gap-2">
                <span className="text-sm font-semibold text-text-primary">{result?.ts_code || codeParam}</span>
                <span className="text-[10px] px-1.5 py-0.5 rounded-md bg-emerald-500/10 text-emerald-400 border border-emerald-500/15">
                  {cachedResult ? "缓存" : "分析完成"}
                </span>
              </div>
              <button
                onClick={() => runDiagnosis(result?.ts_code || codeParam || undefined)}
                className="text-xs text-text-muted hover:text-amber-400 transition-colors flex items-center gap-1"
              >
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M1 4v6h6" />
                  <path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10" />
                </svg>
                重新诊断
              </button>
            </div>
            <div
              className={`text-sm text-text-secondary leading-relaxed prose prose-sm max-w-none [&_h2]:text-sm [&_h2]:font-semibold [&_h2]:text-amber-400 [&_h2]:mt-5 [&_h2]:mb-2 [&_h2]:first:mt-0 [&_h3]:text-xs [&_h3]:font-semibold [&_h3]:text-text-primary [&_h3]:mt-3 [&_h3]:mb-1.5 [&_p]:text-text-secondary [&_p]:mb-2.5 [&_p]:leading-relaxed [&_ul]:text-text-secondary [&_ul]:mb-2.5 [&_li]:mb-1 [&_strong]:text-text-primary ${theme !== "light" ? "prose-invert" : ""}`}
              dangerouslySetInnerHTML={{ __html: markdownToHtml(displayContent) }}
            />
          </div>
        </div>
      )}

      {/* Error */}
      {result?.status === "error" && !loading && !displayContent && (
        <div className="glass-card-static p-8 text-center animate-fade-in-up">
          <div className="text-sm text-red-400 mb-2">诊断失败</div>
          <div className="text-xs text-text-muted">{result.message || "未知错误"}</div>
        </div>
      )}

      {/* Empty state */}
      {!result && !loading && !displayContent && history.length === 0 && (
        <div className="glass-card-static p-10 text-center animate-fade-in-up">
          <div className="w-12 h-12 rounded-2xl bg-surface-2 flex items-center justify-center mx-auto mb-4">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" className="text-text-muted/40">
              <path d="M9 11l3 3L22 4" />
              <path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11" />
            </svg>
          </div>
          <div className="text-sm text-text-muted mb-2">输入股票代码开始 AI 诊断</div>
          <div className="text-xs text-text-muted/50 mb-4">
            支持股票代码（如 600683）或名称（如 京投发展）
          </div>
          <div className="flex flex-wrap justify-center gap-2">
            {["贵州茅台", "宁德时代", "比亚迪"].map((name) => (
              <button
                key={name}
                onClick={() => {
                  setInput(name);
                  searchStock(name);
                }}
                className="text-xs px-3 py-1.5 bg-surface-2 rounded-lg text-text-secondary hover:text-text-primary hover:bg-surface-3 transition-all border border-border-subtle"
              >
                {name}
              </button>
            ))}
          </div>
        </div>
      )}
    </div>
    </ErrorBoundary>
  );
}