import { useEffect, useRef, useState } from "react";
import { Link } from "react-router-dom";
import { useAI } from "../context/AIContext";
import { aiApi, type AIFocus } from "../lib/ai";
import { fetchSkillsForRoute, type AISkill } from "../lib/ai-skills";
import type { ChatMessage } from "../context/AIContext";
import {
  fetchCoachChat,
  sanitizeCoachMessages,
  saveCoachChatApi,
  type SkillNotesIndex,
} from "../lib/skillCardNotes";
import MarkdownMessage from "./MarkdownMessage";
import PixelMascot from "./PixelMascot";

export default function SkillCoachChat({
  principleId,
  focus,
  cardTitle,
  contextHint,
  initialQuestion,
  autoSendToken = 0,
  onNotesIndexChange,
}: {
  principleId: string;
  focus: AIFocus;
  cardTitle: string;
  /** 心法摘要，確保後端 context 一定能附上卡片內容 */
  contextHint?: string;
  initialQuestion?: string;
  /** 每次遞增會觸發一次自動解說（按「問貓頭鷹教練」） */
  autoSendToken?: number;
  onNotesIndexChange?: (notesIndex: SkillNotesIndex) => void;
}) {
  const ai = useAI();
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [chatLoaded, setChatLoaded] = useState(false);
  const [draft, setDraft] = useState("");
  const [busy, setBusy] = useState(false);
  const [skills, setSkills] = useState<AISkill[]>([]);
  const chatRef = useRef<HTMLDivElement>(null);
  const lastAutoTokenRef = useRef(0);
  const abortRef = useRef<AbortController | null>(null);

  useEffect(() => {
    let cancelled = false;
    setChatLoaded(false);
    setBusy(false);
    setDraft("");
    lastAutoTokenRef.current = 0;
    void fetchCoachChat(principleId, cardTitle).then((msgs) => {
      if (cancelled) return;
      setMessages(msgs);
      setChatLoaded(true);
    });
    return () => {
      cancelled = true;
    };
  }, [principleId, cardTitle]);

  useEffect(() => {
    if (!chatLoaded || busy) return;
    const timer = window.setTimeout(() => {
      void saveCoachChatApi(principleId, messages, cardTitle).then(({ notesIndex }) => {
        onNotesIndexChange?.(notesIndex);
      });
    }, 450);
    return () => window.clearTimeout(timer);
  }, [principleId, cardTitle, messages, chatLoaded, busy, onNotesIndexChange]);

  useEffect(() => {
    return () => {
      abortRef.current?.abort();
    };
  }, [principleId]);

  useEffect(() => {
    void ai.refreshStatus();
    void fetchSkillsForRoute("/skills", focus).then(setSkills);
  }, [principleId, focus.cardTitle, focus.label, focus.principleId]);

  useEffect(() => {
    chatRef.current?.scrollTo({ top: chatRef.current.scrollHeight, behavior: "smooth" });
  }, [messages, busy]);

  const send = async (question?: string, skillId?: string) => {
    const q = (question ?? draft).trim();
    if (!q || busy) return;

    if (!ai.status?.ready) {
      setMessages((m) => [
        ...m,
        {
          id: `err-${Date.now()}`,
          role: "system",
          text: "尚未設定 AI API Key。請到「設定 → AI Provider」填入 Grok 或 OpenCode Go 金鑰。",
        },
      ]);
      return;
    }

    abortRef.current?.abort();
    const ctrl = new AbortController();
    abortRef.current = ctrl;

    setBusy(true);
    setDraft("");
    const typingId = `t-${Date.now()}`;
    setMessages((m) => [
      ...sanitizeCoachMessages(m),
      { id: `u-${Date.now()}`, role: "user", text: q },
      { id: typingId, role: "assistant", text: "…", meta: "思考中" },
    ]);

    try {
      const ctx = await aiApi.context(
        "skills",
        { ...focus, principleId, view: "skills", tab: "skills" },
        {
          pathname: "/skills",
          visibleText: contextHint || cardTitle,
        },
      );
      if (ctrl.signal.aborted) return;

      const res = await aiApi.chat({
        provider: ai.provider,
        model: ai.model || undefined,
        question: q,
        context: ctx,
        skillId,
        signal: ctrl.signal,
      });
      if (ctrl.signal.aborted) return;

      setMessages((m) =>
        m.map((msg) =>
          msg.id === typingId
            ? {
                ...msg,
                text: res.text?.trim() || "（AI 沒有回傳文字，請再試一次）",
                meta: [
                  `${res.provider} · ${res.model}`,
                  res.mcp?.hasLiveData ? `MCP: ${res.mcp.summary || "已附即時資料"}` : "",
                ]
                  .filter(Boolean)
                  .join(" · "),
              }
            : msg,
        ),
      );
    } catch (e) {
      if (ctrl.signal.aborted) return;
      const err = e instanceof Error ? e.message : String(e);
      setMessages((m) =>
        m.map((msg) =>
          msg.id === typingId ? { ...msg, text: `呼叫失敗：${err}`, meta: "錯誤" } : msg,
        ),
      );
    } finally {
      if (!ctrl.signal.aborted) setBusy(false);
    }
  };

  useEffect(() => {
    if (!autoSendToken || autoSendToken === lastAutoTokenRef.current || !initialQuestion) return;
    lastAutoTokenRef.current = autoSendToken;
    void send(initialQuestion);
  }, [autoSendToken, initialQuestion]);

  return (
    <section className="skill-coach-chat" aria-label="貓頭鷹教練對話">
      <div className="skill-coach-chat-head">
        <PixelMascot size={48} variant="chat" />
        <div>
          <div className="skill-coach-chat-name">金幣貓頭鷹教練</div>
          <div className="small muted">已附上這張心法卡 · {cardTitle}</div>
        </div>
      </div>

      {!ai.status?.ready && (
        <div className="skill-coach-setup">
          <p>尚未設定 AI。請到設定頁填入 API Key 後即可在這裡直接問。</p>
          <Link to="/settings" className="guide-setup-link">
            前往 AI 設定 →
          </Link>
        </div>
      )}

      <div className="guide-chat skill-coach-messages" ref={chatRef}>
        {messages.map((msg) => (
          <div key={msg.id} className={"guide-msg " + msg.role}>
            {msg.role === "assistant" && <PixelMascot size={28} variant="chat" />}
            <div className="guide-bubble-wrap">
              <div className="guide-bubble">
                <MarkdownMessage text={msg.text} />
              </div>
              {msg.meta && <div className="guide-meta small muted">{msg.meta}</div>}
            </div>
          </div>
        ))}
      </div>

      {skills.length > 0 && (
        <div className="guide-skills skill-coach-skills">
          <div className="guide-skills-k">快捷提問</div>
          <div className="guide-skill-row">
            {skills.map((s) => (
              <button
                key={s.id}
                type="button"
                className="guide-skill"
                disabled={busy}
                onClick={() => void send(s.prompt, s.id)}
              >
                {s.label}
              </button>
            ))}
          </div>
        </div>
      )}

      <div className="guide-compose skill-coach-compose">
        <textarea
          rows={3}
          value={draft}
          placeholder="問這條心法怎麼用…（Enter 送出、Shift+Enter 換行）"
          onChange={(e) => setDraft(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing) {
              e.preventDefault();
              void send();
            }
          }}
        />
        <button type="button" className="guide-send" disabled={busy} onClick={() => void send()}>
          ↑
        </button>
      </div>
    </section>
  );
}
