import { useEffect, useMemo, useState } from "react";
import { Link, useSearchParams } from "react-router-dom";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import PatternDetailPanel from "../components/PatternDetailPanel";
import { AppIcon } from "../components/PixelIcons";
import { Card, ErrorState, Loading, Tag } from "../components/ui";
import { api } from "../lib/api";
import {
  countPatternProgress,
  filterPatterns,
  groupPatternsByChapter,
  isPatternCollected,
  patternArtIcon,
  patternBiasTone,
  patternStatusLabel,
  type PatternChapterGroup,
} from "../lib/patternAtlas";
import { fetchPatternState, markPatternReadApi } from "../lib/patternProgress";
import { syncPlayerProgress } from "../lib/learningSync";
import type { PatternCatalogItem, PatternProgressMap } from "../lib/api";

export default function Patterns() {
  const qc = useQueryClient();
  const [searchParams, setSearchParams] = useSearchParams();
  const catalogQ = useQuery({
    queryKey: ["pattern-catalog"],
    queryFn: api.patternCatalog,
    staleTime: 3600_000,
  });
  const stateQ = useQuery({
    queryKey: ["pattern-state"],
    queryFn: fetchPatternState,
    staleTime: 30_000,
  });

  const [progress, setProgress] = useState<PatternProgressMap>({});
  const [selected, setSelected] = useState<PatternCatalogItem | null>(null);
  const [openTab, setOpenTab] = useState<"detail" | "book" | "scan">("detail");
  const [query, setQuery] = useState("");
  const [chapter, setChapter] = useState("all");
  const [collapsed, setCollapsed] = useState<Record<number, boolean>>({});
  const [scanSymbol, setScanSymbol] = useState("");

  useEffect(() => {
    if (stateQ.data) setProgress(stateQ.data);
  }, [stateQ.data]);

  const patterns = catalogQ.data?.patterns || [];
  const chapterNames = catalogQ.data?.chapterNames || {};
  const stats = useMemo(() => countPatternProgress(patterns, progress), [patterns, progress]);
  const filtered = useMemo(() => filterPatterns(patterns, query, chapter), [patterns, query, chapter]);
  const groups = useMemo(
    () => groupPatternsByChapter(filtered, chapterNames),
    [filtered, chapterNames],
  );

  const patternById = useMemo(() => {
    const map = new Map<string, PatternCatalogItem>();
    for (const p of patterns) map.set(p.id, p);
    return map;
  }, [patterns]);

  useEffect(() => {
    const pid = searchParams.get("pattern");
    if (!pid || !patterns.length) return;
    const hit = patternById.get(pid);
    if (hit) {
      setSelected(hit);
      setOpenTab(searchParams.get("tab") === "scan" ? "scan" : "detail");
      void markPatternReadApi(pid).then((p) => {
        setProgress(p);
        syncPlayerProgress(qc);
      });
    }
  }, [searchParams, patterns.length, patternById]);

  const openPattern = (
    p: PatternCatalogItem,
    tab: "detail" | "book" | "scan" = "detail",
  ) => {
    setOpenTab(tab);
    setSelected(p);
    const next = new URLSearchParams(searchParams);
    next.set("pattern", p.id);
    if (tab !== "detail") next.set("tab", tab);
    else next.delete("tab");
    setSearchParams(next, { replace: true });
    void markPatternReadApi(p.id).then((prog) => {
      setProgress(prog);
      syncPlayerProgress(qc);
    });
  };

  const closePattern = () => {
    setSelected(null);
    const next = new URLSearchParams(searchParams);
    next.delete("pattern");
    next.delete("tab");
    setSearchParams(next, { replace: true });
  };

  if (catalogQ.isLoading || stateQ.isLoading) return <Loading label="載入線型圖鑑…" />;
  if (catalogQ.error || !catalogQ.data) {
    return <ErrorState detail={(catalogQ.error as Error)?.message} />;
  }

  const source = catalogQ.data.source || "短線交易日線圖大全";

  return (
    <div className="pattern-page">
      <div className="page-head">
        <div className="eyebrow">修煉 · 技術</div>
        <h1 className="page-title-row">
          <AppIcon name="cards" size={38} framed glow variant="hero" />
          線型圖鑑
        </h1>
        <p>
          全書 {stats.total} 項線型招式，其中 {stats.automatable} 項可自動掃描。打開卡牌入圖鑑，再到個股圖表實戰驗證。
        </p>
      </div>

      <Card className="skill-progress-card skill-quest-board pat-progress-card">
        <div className="skill-progress-row">
          <div className="kpi skill-kpi">
            <div className="k-v">
              {stats.collected} / {stats.total}
            </div>
            <div className="k-l">已收集招式</div>
          </div>
          <div className="skill-progress-bar-wrap">
            <div className="xp-label">
              <span>圖鑑進度</span>
              <span>{stats.pct}%</span>
            </div>
            <div className="bar">
              <span style={{ width: `${stats.pct}%` }} />
            </div>
          </div>
          <div className="skill-progress-side">
            <Tag tone={stats.automatableCollected >= stats.automatable ? "gold" : "cool"}>
              可掃描 {stats.automatableCollected}/{stats.automatable}
            </Tag>
            <span className="small muted">
              實戰見過 {stats.scanned} 項 · 《{source}》
            </span>
          </div>
        </div>
      </Card>

      <Card className="pad-sm pat-scan-quick">
        <div className="pat-scan-quick-head">
          <AppIcon name="compass" size={20} framed variant="hero" />
          <strong>快速實戰掃描</strong>
        </div>
        <p className="small muted">輸入代號，從圖鑑內任一可掃描線型開始驗證。</p>
        <div className="pat-scan-form">
          <input
            type="text"
            className="pat-scan-input backpack-filter"
            placeholder="NVDA 或 2330"
            value={scanSymbol}
            onChange={(e) => setScanSymbol(e.target.value)}
            spellCheck={false}
          />
          <button
            type="button"
            className="btn-primary sm"
            disabled={!scanSymbol.trim()}
            onClick={() => {
              const auto = patterns.find((p) => p.automatable);
              if (auto) openPattern(auto, "scan");
              else if (patterns[0]) openPattern(patterns[0], "detail");
            }}
          >
            開啟掃描
          </button>
          {scanSymbol.trim() ? (
            <Link
              to={`/research?sym=${encodeURIComponent(scanSymbol.trim().toUpperCase())}`}
              className="btn-ghost sm"
            >
              個股圖表 →
            </Link>
          ) : null}
        </div>
      </Card>

      <div className="skill-toolbar pat-toolbar">
        <input
          type="search"
          className="skill-search backpack-filter"
          placeholder="搜尋線型招式…"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          spellCheck={false}
        />
        <select
          className="pat-chapter-select backpack-filter"
          value={chapter}
          onChange={(e) => setChapter(e.target.value)}
        >
          <option value="all">全部章節</option>
          {(catalogQ.data.chapters || []).map((ch) => (
            <option key={ch.id} value={String(ch.id)}>
              {ch.name}
            </option>
          ))}
        </select>
        {query || chapter !== "all" ? (
          <button
            type="button"
            className="btn-ghost sm"
            onClick={() => {
              setQuery("");
              setChapter("all");
            }}
          >
            清除
          </button>
        ) : null}
      </div>

      {!filtered.length ? (
        <p className="muted">找不到符合條件的線型，試試其他關鍵字或章節。</p>
      ) : (
        groups.map((g) => (
          <PatternChapterSection
            key={g.id}
            group={g}
            progress={progress}
            collapsed={!!collapsed[g.id]}
            selectedId={selected?.id}
            onToggle={() => setCollapsed((c) => ({ ...c, [g.id]: !c[g.id] }))}
            onOpen={openPattern}
          />
        ))
      )}

      <PatternDetailPanel
        pattern={selected}
        progress={progress}
        onClose={closePattern}
        onProgressChange={setProgress}
        initialTab={openTab}
        initialSymbol={scanSymbol}
      />

      <div className="disclaimer">本工具僅供學習觀測，所有內容不構成投資建議</div>
    </div>
  );
}

function PatternChapterSection({
  group,
  progress,
  collapsed,
  selectedId,
  onToggle,
  onOpen,
}: {
  group: PatternChapterGroup;
  progress: PatternProgressMap;
  collapsed: boolean;
  selectedId?: string;
  onToggle: () => void;
  onOpen: (p: PatternCatalogItem, tab?: "detail" | "book" | "scan") => void;
}) {
  const collected = group.patterns.filter((p) => isPatternCollected(progress[p.id])).length;
  return (
    <section className="skill-group pat-chapter">
      <button
        type="button"
        className="skill-group-head"
        onClick={onToggle}
        aria-expanded={!collapsed}
      >
        <h3>
          <AppIcon name="scroll" size={22} framed variant="hero" />
          {group.name}
          <Tag>
            {collected}/{group.patterns.length}
          </Tag>
        </h3>
        <span className="skill-group-when">
          {group.patterns.filter((p) => p.automatable).length} 項可掃描
        </span>
        <span className="skill-group-toggle">{collapsed ? "▼ 展開" : "▲ 收合"}</span>
      </button>
      {!collapsed ? (
        <div className="skill-row card-wall pat-card-wall">
          {group.patterns.map((p) => {
            const entry = progress[p.id];
            const collected = isPatternCollected(entry);
            const artIcon = patternArtIcon(p.bias, p.automatable);
            const cls = [
              "skill-node",
              "pat-node",
              collected ? "collected" : "",
              p.automatable ? "pat-node--scan" : "",
              selectedId === p.id ? "selected" : "",
            ]
              .filter(Boolean)
              .join(" ");
            return (
              <button key={p.id} type="button" className={cls} onClick={() => onOpen(p)}>
                <div className="sn-art" aria-hidden>
                  <AppIcon
                    name={artIcon}
                    size={36}
                    framed
                    glow={collected}
                    variant="hero"
                  />
                  {collected ? (
                    <span className="sn-art-master">
                      <AppIcon name="coin" size={16} framed variant="nav" />
                    </span>
                  ) : null}
                  {p.automatable ? <span className="pat-scan-badge" title="可掃描">⚡</span> : null}
                </div>
                <div className="sn-body">
                  <div className="sn-nm">{p.name}</div>
                  <div className="sn-foot">
                    <span className="sn-mastery">{patternStatusLabel(entry)}</span>
                    <span className="sn-foot-tags">
                      <Tag tone={patternBiasTone(p.bias)}>{p.category}</Tag>
                    </span>
                  </div>
                </div>
              </button>
            );
          })}
        </div>
      ) : null}
    </section>
  );
}