import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { useMutation, useQuery } from "@tanstack/react-query";
import { AppIcon } from "./PixelIcons";
import { Tag, Loading } from "./ui";
import {
  api,
  type PatternCatalogItem,
  type PatternProgressMap,
  type PatternSignal,
} from "../lib/api";
import {
  patternArtIcon,
  patternBiasLabel,
  patternBiasTone,
  patternStatusLabel,
} from "../lib/patternAtlas";
import { recordPatternScanHitsApi } from "../lib/patternProgress";

type PatternTab = "detail" | "book" | "scan";

export default function PatternDetailPanel({
  pattern,
  progress,
  onClose,
  onProgressChange,
  initialTab = "detail",
  initialSymbol = "",
}: {
  pattern: PatternCatalogItem | null;
  progress: PatternProgressMap;
  onClose: () => void;
  onProgressChange: (map: PatternProgressMap) => void;
  initialTab?: PatternTab;
  initialSymbol?: string;
}) {
  const open = !!pattern;
  const [tab, setTab] = useState<PatternTab>("detail");
  const [symbol, setSymbol] = useState(initialSymbol);
  const [scan, setScan] = useState<{
    display?: string;
    symbol: string;
    market?: string;
    signalCount?: number;
    recentSignals?: PatternSignal[];
    signals?: PatternSignal[];
  } | null>(null);

  const scanMut = useMutation({
    mutationFn: async ({ sym, onlyThis }: { sym: string; onlyThis?: boolean }) => {
      const data = await api.patternScan(sym, "2y", 120);
      const pid = pattern?.id;
      const filtered =
        onlyThis && pid
          ? (data.signals || []).filter((s) => s.patternId === pid).slice(0, 15)
          : (data.recentSignals || data.signals || []).slice(0, 15);
      return { ...data, recentSignals: filtered, hitIds: filtered.map((s) => s.patternId).filter(Boolean) as string[] };
    },
    onSuccess: async (data) => {
      setScan(data);
      const ids = [...new Set(data.hitIds || [])];
      if (ids.length) {
        const map = await recordPatternScanHitsApi(ids);
        onProgressChange(map);
      }
    },
  });

  const teach = pattern?.teach || {};
  const bookPage =
    teach.bookHtml || (teach.bookRef ? teach.bookRef.replace(/\.md$/i, ".html") : null);
  const bookPageId = bookPage?.replace(/\.html?$/i, "") || "";
  const bookQ = useQuery({
    queryKey: ["pattern-book", bookPageId],
    queryFn: () => api.patternBookPage(bookPageId),
    enabled: open && !!bookPageId && tab === "book",
    staleTime: 3600_000,
  });
  useEffect(() => {
    if (!open) return;
    setTab(initialTab);
    setSymbol(initialSymbol);
    setScan(null);
    document.body.classList.add("skill-modal-open");
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") onClose();
    };
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("keydown", onKey);
      document.body.classList.remove("skill-modal-open");
    };
  }, [open, pattern?.id, onClose, initialTab, initialSymbol]);

  if (!open || !pattern) return null;

  const entry = progress[pattern.id];
  const biasTone = patternBiasTone(pattern.bias);
  const artIcon = patternArtIcon(pattern.bias, pattern.automatable);
  const signals = scan?.recentSignals || scan?.signals || [];

  const runScan = (onlyThis = false) => {
    const sym = symbol.trim();
    if (!sym) return;
    scanMut.mutate({ sym, onlyThis });
  };

  return (
    <div className="skill-modal pat-modal" role="dialog" aria-modal="true" aria-labelledby="pat-card-title">
      <button type="button" className="skill-modal-backdrop" aria-label="關閉線型卡" onClick={onClose} />
      <div
        className={[
          "skill-modal-panel",
          "skill-modal-panel--tabbed",
          "pat-modal-panel",
          pattern.automatable ? "pat-modal--scan" : "",
          tab === "book" ? "pat-modal--book" : "",
        ]
          .filter(Boolean)
          .join(" ")}
      >
        <div className="skill-modal-banner" aria-hidden>
          <AppIcon name={artIcon} size={32} framed glow variant="hero" />
        </div>
        <div className="skill-modal-head">
          <AppIcon name={artIcon} size={26} framed variant="hero" />
          <strong>線型招式</strong>
          <div className="skill-modal-tabs" role="tablist" aria-label="線型卡分頁">
            <button
              type="button"
              role="tab"
              aria-selected={tab === "detail"}
              className={"skill-modal-tab" + (tab === "detail" ? " active" : "")}
              onClick={() => setTab("detail")}
            >
              詳情
            </button>
            {bookPage ? (
              <button
                type="button"
                role="tab"
                aria-selected={tab === "book"}
                className={"skill-modal-tab" + (tab === "book" ? " active" : "")}
                onClick={() => setTab("book")}
              >
                教材卷軸
              </button>
            ) : null}
            {pattern.automatable ? (
              <button
                type="button"
                role="tab"
                aria-selected={tab === "scan"}
                className={"skill-modal-tab" + (tab === "scan" ? " active" : "")}
                onClick={() => setTab("scan")}
              >
                實戰掃描
              </button>
            ) : null}
          </div>
          <button type="button" className="skill-modal-close" onClick={onClose} aria-label="關閉">
            ×
          </button>
        </div>

        <div className="skill-modal-body pat-modal-body">
          <div className="pat-detail-head">
            <h2 id="pat-card-title">{pattern.name}</h2>
            <div className="pat-detail-tags">
              <Tag tone={biasTone}>{patternBiasLabel(pattern.bias)}</Tag>
              {pattern.automatable ? <Tag tone="cool">可掃描</Tag> : <Tag>教學</Tag>}
              <span className="small muted">{patternStatusLabel(entry)}</span>
            </div>
            <p className="small muted pat-detail-meta">
              {pattern.category}
              {pattern.timeframe?.length ? ` · ${pattern.timeframe.join(" / ")}` : ""}
              {pattern.bookPage ? ` · 書本 p.${pattern.bookPage}` : ""}
            </p>
          </div>

          {tab === "detail" ? (
            <div className="pat-teach-block">
              {teach.fullTitle && teach.fullTitle !== pattern.name ? (
                <p className="small muted">{teach.fullTitle}</p>
              ) : null}
              <p className="pat-summary">{teach.summary || "尚無摘要。"}</p>
              <div className="pat-teach-grid">
                <div>
                  <b>進場參考</b>
                  <p>{teach.entryHint || "—"}</p>
                </div>
                <div>
                  <b>出場參考</b>
                  <p>{teach.exitHint || "—"}</p>
                </div>
                <div>
                  <b>注意</b>
                  <p>{teach.caution || "—"}</p>
                </div>
              </div>
              <div className="pat-detail-actions">
                {bookPage ? (
                  <button type="button" className="btn-ghost sm" onClick={() => setTab("book")}>
                    開啟教材卷軸 →
                  </button>
                ) : null}
                {pattern.automatable ? (
                  <button type="button" className="btn-primary sm" onClick={() => setTab("scan")}>
                    實戰掃描
                  </button>
                ) : null}
                <Link
                  to={symbol.trim() ? `/research?sym=${encodeURIComponent(symbol.trim().toUpperCase())}` : "/research"}
                  className="btn-ghost sm"
                >
                  在個股圖表看 →
                </Link>
              </div>
            </div>
          ) : null}

          {tab === "book" && bookPage ? (
            <div className="pat-book-block">
              <p className="small muted">
                教材出處：{bookQ.data?.title || pattern.name}
                {(bookQ.data?.pageNum || pattern.bookPage)
                  ? ` · 第 ${bookQ.data?.pageNum || pattern.bookPage} 頁`
                  : teach.isSupplement || bookQ.data?.isSupplement
                    ? ` · ${teach.tocHint || bookQ.data?.tocHint || "教材補遺"}`
                    : ""}
              </p>
              {bookQ.isLoading ? <Loading label="載入教材內容…" /> : null}
              {bookQ.data?.html ? (
                <iframe
                  className="pat-book-frame"
                  srcDoc={bookQ.data.html}
                  title={pattern.name}
                />
              ) : null}
            </div>
          ) : null}

          {tab === "scan" && pattern.automatable ? (
            <div className="pat-scan-block">
              <p className="small muted">
                輸入代號掃描近期 K 線，對照書中可偵測的 18 招線型。結果會標記在個股圖表上。
              </p>
              <div className="pat-scan-form">
                <input
                  type="text"
                  className="pat-scan-input"
                  placeholder="NVDA 或 2330"
                  value={symbol}
                  onChange={(e) => setSymbol(e.target.value)}
                  onKeyDown={(e) => {
                    if (e.key === "Enter") runScan(true);
                  }}
                  spellCheck={false}
                />
                <button
                  type="button"
                  className="btn-primary sm"
                  disabled={scanMut.isPending || !symbol.trim()}
                  onClick={() => runScan(true)}
                >
                  {scanMut.isPending ? "掃描中…" : "掃描此線型"}
                </button>
                <button
                  type="button"
                  className="btn-ghost sm"
                  disabled={scanMut.isPending || !symbol.trim()}
                  onClick={() => runScan(false)}
                >
                  全線型掃描
                </button>
              </div>
              {scanMut.isPending ? <Loading label="掃描線型…" /> : null}
              {scan ? (
                <p className="small muted">
                  {scan.display || scan.symbol}
                  {scan.market ? ` · ${scan.market === "tw" ? "台股" : "美股"}` : ""}
                  {" · "}
                  找到 {scan.signalCount || signals.length} 個訊號
                </p>
              ) : null}
              {signals.length ? (
                <ul className="pat-signal-list">
                  {signals.map((s, i) => (
                    <li key={`${s.patternId}-${s.date}-${i}`}>
                      <button
                        type="button"
                        className="pat-signal-btn"
                        onClick={() => {
                          if (symbol.trim()) {
                            window.location.href = `/research?sym=${encodeURIComponent(symbol.trim().toUpperCase())}`;
                          }
                        }}
                      >
                        <span className="pat-signal-name">{s.patternName || s.name}</span>
                        <span className="pat-signal-meta">
                          {s.date}
                          {s.confidence != null ? ` · 信心 ${Math.round(s.confidence * 100)}%` : ""}
                          {s.actionLabel ? ` · ${s.actionLabel}` : ""}
                        </span>
                      </button>
                    </li>
                  ))}
                </ul>
              ) : scan && !scanMut.isPending ? (
                <p className="muted small">此區間未偵測到符合的線型，可換代號或拉長區間再試。</p>
              ) : null}
              {symbol.trim() ? (
                <div className="pat-detail-actions">
                  <Link
                    to={`/research?sym=${encodeURIComponent(symbol.trim().toUpperCase())}`}
                    className="btn-primary sm"
                  >
                    開個股圖表 →
                  </Link>
                </div>
              ) : null}
            </div>
          ) : null}

          <p className="disclaimer pat-disclaimer">
            訊號僅供學習與練習，不構成投資建議。書本強調：先釐清原因與趨勢，再依線型行動。
          </p>
        </div>
      </div>
    </div>
  );
}
