/**
 * 语录博客流:按交易日分组 · 截断展开 · 当日盈亏摘要 · AI 复盘跳转.
 */
(function () {
  const page = document.getElementById("page-quotes");
  if (!page) return;

  const elFeed = document.getElementById("quotes-feed");
  const elStatus = document.getElementById("quotes-status");
  const elBtnRefresh = document.getElementById("quotes-btn-refresh");
  const elLinkArchive = document.getElementById("quotes-link-archive");

  const RECENT_LIMIT = 20;
  const PREVIEW_LEN = 140;
  const ARCHIVE_QUOTE_AI_KEY = "hub_archive_quote_ai";

  let quotes = [];
  let dayStats = {};
  let expanded = {};
  let inited = false;
  let loading = false;

  function esc(s) {
    return String(s == null ? "" : s)
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;");
  }

  async function apiFetch(url, opts) {
    return fetch(url, Object.assign({ credentials: "same-origin" }, opts || {}));
  }

  function setStatus(text) {
    if (elStatus) elStatus.textContent = text || "";
  }

  function findQuote(id) {
    return (
      quotes.find(function (q) {
        return String(q.id) === String(id);
      }) || null
    );
  }

  function fmtPnl(v) {
    const n = Number(v);
    if (!Number.isFinite(n)) return "—";
    return (n >= 0 ? "+" : "") + n.toFixed(2) + "U";
  }

  function pnlClass(v) {
    const n = Number(v);
    if (!Number.isFinite(n) || n === 0) return "";
    return n > 0 ? "pnl-pos" : "pnl-neg";
  }

  function fmtWinRate(v) {
    const n = Number(v);
    if (!Number.isFinite(n)) return "—";
    return n.toFixed(1) + "%";
  }

  function daySummaryHtml(day, st) {
    if (!st) {
      return '<span class="quotes-day-summary muted">当日统计加载中…</span>';
    }
    const openN = Number(st.open_count) || 0;
    const pnl = st.pnl_total;
    return (
      '<span class="quotes-day-summary">' +
      openN +
      " 笔 · 盈亏 <span class=\"" +
      pnlClass(pnl) +
      '">' +
      esc(fmtPnl(pnl)) +
      "</span> · 胜率 " +
      esc(fmtWinRate(st.win_rate)) +
      "</span>"
    );
  }

  function previewText(raw) {
    const text = String(raw || "").trim();
    if (text.length <= PREVIEW_LEN) return { text: text, truncated: false };
    return { text: text.slice(0, PREVIEW_LEN).trim() + "…", truncated: true };
  }

  function groupByDay(rows) {
    const map = {};
    const order = [];
    rows.forEach(function (q) {
      const day = String(q.quote_date || "").slice(0, 10) || "—";
      if (!map[day]) {
        map[day] = [];
        order.push(day);
      }
      map[day].push(q);
    });
    return { map: map, order: order };
  }

  function renderFeed() {
    if (!elFeed) return;
    if (!quotes.length) {
      elFeed.innerHTML =
        '<p class="quotes-empty">暂无复盘语录.可在「内照明心 → 复盘语录」中添加.</p>';
      return;
    }
    const grouped = groupByDay(quotes);
    elFeed.innerHTML = grouped.order
      .map(function (day) {
        const list = grouped.map[day] || [];
        const cards = list
          .map(function (q) {
            const id = String(q.id);
            const full = String(q.content || "").trim();
            const isOpen = !!expanded[id];
            const prev = previewText(full);
            const showExpand = prev.truncated;
            const body = isOpen || !showExpand ? full : prev.text;
            return (
              '<article class="quotes-card' +
              (isOpen ? " is-expanded" : "") +
              '" data-id="' +
              esc(id) +
              '">' +
              '<div class="quotes-card-body">' +
              esc(body) +
              "</div>" +
              '<div class="quotes-card-actions">' +
              (showExpand
                ? '<button type="button" class="ghost quotes-expand-btn" data-id="' +
                  esc(id) +
                  '">' +
                  (isOpen ? "收起" : "展开") +
                  "</button>"
                : "") +
              '<button type="button" class="ghost quotes-ai-btn" data-id="' +
              esc(id) +
              '">AI 复盘</button>' +
              "</div></article>"
            );
          })
          .join("");
        return (
          '<section class="quotes-day-group" data-day="' +
          esc(day) +
          '">' +
          '<header class="quotes-day-head">' +
          '<h2 class="quotes-day-title">' +
          esc(day) +
          "</h2>" +
          daySummaryHtml(day, dayStats[day]) +
          "</header>" +
          '<div class="quotes-day-cards">' +
          cards +
          "</div></section>"
        );
      })
      .join("");

    elFeed.querySelectorAll(".quotes-expand-btn").forEach(function (btn) {
      btn.addEventListener("click", function () {
        const id = btn.getAttribute("data-id");
        expanded[id] = !expanded[id];
        renderFeed();
      });
    });
    elFeed.querySelectorAll(".quotes-ai-btn").forEach(function (btn) {
      btn.addEventListener("click", function () {
        startQuoteAiChat(btn.getAttribute("data-id"));
      });
    });
  }

  function startQuoteAiChat(quoteId) {
    const q = findQuote(quoteId);
    const content = q && String(q.content || "").trim();
    if (!q || !content) {
      setStatus("语录内容为空,无法发起 AI 对话");
      return;
    }
    try {
      sessionStorage.setItem(
        ARCHIVE_QUOTE_AI_KEY,
        JSON.stringify({
          quote_date: q.quote_date || "",
          content: content,
        })
      );
    } catch (_) {
      setStatus("无法保存跳转数据");
      return;
    }
    if (typeof window.hubNavigateTo === "function") {
      window.hubNavigateTo("/ai");
      return;
    }
    location.href = "/ai";
  }

  async function loadDayStats(days) {
    const uniq = [];
    const seen = {};
    (days || []).forEach(function (d) {
      const day = String(d || "").slice(0, 10);
      if (!day || day === "—" || seen[day]) return;
      seen[day] = true;
      uniq.push(day);
    });
    await Promise.all(
      uniq.map(async function (day) {
        if (dayStats[day]) return;
        try {
          const q = new URLSearchParams();
          q.set("period", "today");
          q.set("trading_day", day);
          const r = await apiFetch("/api/archive/daily-trades?" + q.toString());
          const j = await r.json();
          if (r.ok) {
            dayStats[day] = j.stats || { open_count: 0, pnl_total: 0, win_rate: null };
          } else {
            dayStats[day] = { open_count: 0, pnl_total: 0, win_rate: null };
          }
        } catch (_) {
          dayStats[day] = { open_count: 0, pnl_total: 0, win_rate: null };
        }
      })
    );
  }

  async function loadQuotes() {
    if (loading) return;
    loading = true;
    setStatus("加载语录…");
    try {
      const r = await apiFetch("/api/archive/quotes");
      const j = await r.json();
      if (!r.ok) {
        setStatus(j.detail || "加载失败");
        return;
      }
      quotes = (j.quotes || []).slice(0, RECENT_LIMIT);
      const days = quotes.map(function (q) {
        return q.quote_date;
      });
      renderFeed();
      await loadDayStats(days);
      renderFeed();
      setStatus("最近 " + quotes.length + " 条 · " + new Date().toLocaleTimeString());
    } catch (e) {
      setStatus(String(e && e.message ? e.message : e) || "加载失败");
    } finally {
      loading = false;
    }
  }

  function bindEvents() {
    if (elBtnRefresh) elBtnRefresh.addEventListener("click", loadQuotes);
    if (elLinkArchive) {
      elLinkArchive.addEventListener("click", function (ev) {
        if (typeof window.hubNavigateTo === "function") {
          ev.preventDefault();
          window.hubNavigateTo("/archive");
        }
      });
    }
  }

  async function init() {
    if (!page || page.classList.contains("hidden")) return;
    if (!inited) {
      bindEvents();
      inited = true;
    }
    await loadQuotes();
  }

  function destroy() {}

  window.hubQuotesPage = { init: init, destroy: destroy };
})();
