/**
 * 开仓计划:新建 / 进行中 / 历史 / 胜率统计
 */
(function () {
  const page = document.getElementById("page-plan");
  if (!page) return;

  let meta = null;
  let activePlans = [];
  let archivedPlans = [];
  let statsPeriod = "all";
  let statsDim = "symbol";
  let statsDateFrom = "";
  let statsDateTo = "";
  let editingPlanId = null;
  let inited = false;

  function $(id) {
    return document.getElementById(id);
  }

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

  function toast(msg, isErr) {
    const el = $("toast");
    if (!el) return;
    el.textContent = msg;
    el.className = isErr ? "err" : "ok";
    clearTimeout(el._t);
    el._t = setTimeout(function () {
      el.className = "";
      el.textContent = "";
    }, 3200);
  }

  async function api(path, opts) {
    const r = await fetch(path, Object.assign({ credentials: "same-origin" }, opts || {}));
    let data = {};
    try {
      data = await r.json();
    } catch (_e) {
      data = {};
    }
    if (!r.ok) {
      const detail = (data && data.detail) || r.statusText || "请求失败";
      throw new Error(typeof detail === "string" ? detail : JSON.stringify(detail));
    }
    return data;
  }

  function todayIso() {
    const d = new Date();
    const y = d.getFullYear();
    const m = String(d.getMonth() + 1).padStart(2, "0");
    const day = String(d.getDate()).padStart(2, "0");
    return y + "-" + m + "-" + day;
  }

  function exchangeLabel(key) {
    const ex = (meta && meta.exchanges) || [];
    const row = ex.find(function (e) {
      return String(e.key) === String(key);
    });
    return (row && row.name) || key || "—";
  }

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

  function fillSelect(el, options, valueKey, labelKey) {
    if (!el) return;
    el.innerHTML = "";
    (options || []).forEach(function (opt) {
      const o = document.createElement("option");
      if (typeof opt === "string") {
        o.value = opt;
        o.textContent = opt;
      } else {
        o.value = opt[valueKey];
        o.textContent = opt[labelKey];
      }
      el.appendChild(o);
    });
  }

  function renderDirectionRadios(container, name, selected) {
    if (!container || !meta) return;
    container.innerHTML = "";
    (meta.directions || []).forEach(function (d) {
      const label = document.createElement("label");
      label.className = "plan-radio-label";
      const input = document.createElement("input");
      input.type = "radio";
      input.name = name;
      input.value = d.value;
      if (d.value === selected) input.checked = true;
      label.appendChild(input);
      label.appendChild(document.createTextNode(" " + d.label));
      container.appendChild(label);
    });
  }

  function bindMetaToCreateForm() {
    fillSelect($("plan-create-exchange"), meta.exchanges, "key", "name");
    fillSelect($("plan-create-type"), meta.plan_types, "value", "label");
    fillSelect($("plan-create-trend-tf"), meta.trend_timeframes);
    fillSelect($("plan-create-entry-tf"), meta.entry_timeframes);
    renderDirectionRadios($("plan-create-direction"), "plan-direction", "long");
    const dateEl = $("plan-create-date");
    if (dateEl && !dateEl.value) dateEl.value = todayIso();
  }

  function planSummaryLine(p) {
    return (
      esc(p.symbol) +
      " · " +
      esc(exchangeLabel(p.exchange_key)) +
      " · " +
      esc(p.direction_label || p.direction) +
      " · " +
      esc(p.plan_type_label || p.plan_type)
    );
  }

  function schemeOptionsHtml(selected) {
    let html = '<option value="">请选择</option>';
    (meta.entry_schemes || []).forEach(function (s) {
      html +=
        '<option value="' +
        esc(s.value) +
        '"' +
        (selected === s.value ? " selected" : "") +
        ">" +
        esc(s.label) +
        "</option>";
    });
    return html;
  }

  function renderActiveList() {
    const host = $("plan-active-list");
    const cnt = $("plan-active-count");
    if (!host) return;
    if (cnt) cnt.textContent = activePlans.length ? activePlans.length + " 条" : "";
    if (!activePlans.length) {
      host.innerHTML = '<p class="plan-empty">暂无进行中的计划</p>';
      return;
    }
    host.innerHTML = activePlans
      .map(function (p) {
        return (
          '<article class="plan-active-card" data-id="' +
          esc(p.id) +
          '">' +
          '<div class="plan-active-head">' +
          '<div class="plan-active-title">' +
          planSummaryLine(p) +
          "</div>" +
          '<div class="plan-active-actions">' +
          '<button type="button" class="ghost plan-btn-edit" data-id="' +
          esc(p.id) +
          '">修改</button>' +
          '<button type="button" class="ghost plan-btn-del" data-id="' +
          esc(p.id) +
          '">删除</button>' +
          "</div></div>" +
          '<div class="plan-active-meta">' +
          esc(p.plan_date) +
          " · 趋势 " +
          esc(p.trend_timeframe) +
          " / 入场 " +
          esc(p.entry_timeframe) +
          "</div>" +
          '<div class="plan-active-levels">目标 ' +
          esc(p.target_level || "—") +
          " · 区间 " +
          esc(p.current_range || "—") +
          "</div>" +
          (p.note ? '<div class="plan-active-note">' + esc(p.note) + "</div>" : "") +
          '<div class="plan-scheme-row">' +
          '<label class="plan-field plan-field-inline plan-field-scheme"><span>入场方案</span>' +
          '<select class="plan-active-scheme" data-id="' +
          esc(p.id) +
          '">' +
          schemeOptionsHtml(p.entry_scheme || "") +
          "</select></label>" +
          "</div>" +
          '<div class="plan-close-row">' +
          '<label class="plan-field plan-field-inline"><span>结果</span>' +
          '<select class="plan-close-result" data-id="' +
          esc(p.id) +
          '"><option value="">—</option>' +
          (meta.results || [])
            .map(function (r) {
              return (
                '<option value="' +
                esc(r.value) +
                '"' +
                (p.result === r.value ? " selected" : "") +
                ">" +
                esc(r.label) +
                "</option>"
              );
            })
            .join("") +
          "</select></label>" +
          '<label class="plan-field plan-field-inline"><span>盈亏</span>' +
          '<input class="plan-close-pnl" data-id="' +
          esc(p.id) +
          '" type="number" step="any" placeholder="U(可选)" value="' +
          (p.pnl_amount != null ? esc(p.pnl_amount) : "") +
          '" /></label>' +
          '<button type="button" class="primary plan-btn-archive" data-id="' +
          esc(p.id) +
          '">填写结果并归档</button>' +
          "</div></article>"
        );
      })
      .join("");
  }

  function renderHistoryList() {
    const host = $("plan-history-list");
    const cnt = $("plan-history-count");
    if (!host) return;
    if (cnt) cnt.textContent = archivedPlans.length ? archivedPlans.length + " 条" : "";
    if (!archivedPlans.length) {
      host.innerHTML = '<p class="plan-empty">暂无历史计划</p>';
      return;
    }
    host.innerHTML = archivedPlans
      .map(function (p) {
        const pnlTxt = fmtPnl(p.pnl_amount);
        const resCls = p.result === "win" ? "plan-res-win" : "plan-res-loss";
        return (
          '<button type="button" class="plan-history-row" data-id="' +
          esc(p.id) +
          '">' +
          '<span class="plan-history-date">' +
          esc(p.plan_date) +
          "</span>" +
          '<span class="plan-history-main">' +
          esc(p.symbol) +
          " · " +
          esc(exchangeLabel(p.exchange_key)) +
          "</span>" +
          '<span class="plan-history-scheme">' +
          esc(p.entry_scheme_label || p.entry_scheme) +
          "</span>" +
          '<span class="plan-history-result ' +
          resCls +
          '">' +
          esc(p.result_label || p.result) +
          (pnlTxt ? " " + esc(pnlTxt) : "") +
          "</span></button>"
        );
      })
      .join("");
  }

  function renderStatsTable(stats) {
    const host = $("plan-stats-table");
    const labelEl = $("plan-stats-label");
    if (labelEl) labelEl.textContent = (stats && stats.period_label) || "";
    if (!host) return;
    const items = (stats && stats.items) || [];
    if (!items.length) {
      host.innerHTML = '<p class="plan-empty">该范围内暂无已归档且有结果的计划</p>';
      return;
    }
    const dimLabel =
      stats.dimension === "trend_tf"
        ? "趋势周期"
        : stats.dimension === "entry_scheme"
          ? "入场方案"
          : "币种";
    let rows = items
      .map(function (it) {
        return (
          "<tr><td>" +
          esc(it.label || it.key) +
          "</td><td>" +
          (it.total || 0) +
          "</td><td>" +
          (it.win_count || 0) +
          "</td><td>" +
          (it.loss_count || 0) +
          "</td><td>" +
          (it.win_rate != null ? it.win_rate + "%" : "—") +
          "</td></tr>"
        );
      })
      .join("");
    host.innerHTML =
      '<table class="plan-stats-table"><thead><tr>' +
      "<th>" +
      esc(dimLabel) +
      "</th><th>计划数</th><th>盈利</th><th>亏损</th><th>胜率</th>" +
      "</tr></thead><tbody>" +
      rows +
      "</tbody></table>";
  }

  function statsQuery() {
    const q = new URLSearchParams();
    q.set("dimension", statsDim);
    q.set("period", statsPeriod);
    if (statsPeriod === "range") {
      if (statsDateFrom) q.set("date_from", statsDateFrom);
      if (statsDateTo) q.set("date_to", statsDateTo);
    }
    return q.toString();
  }

  async function loadMeta() {
    const data = await api("/api/entry-plans/meta");
    meta = data;
    bindMetaToCreateForm();
  }

  async function loadActive() {
    const data = await api("/api/entry-plans?status=active");
    activePlans = data.plans || [];
    renderActiveList();
  }

  async function loadHistory() {
    const data = await api("/api/entry-plans?status=archived");
    archivedPlans = data.plans || [];
    renderHistoryList();
  }

  async function loadStats() {
    const data = await api("/api/entry-plans/stats?" + statsQuery());
    renderStatsTable(data.stats || {});
  }

  async function refreshAll() {
    await Promise.all([loadActive(), loadHistory(), loadStats()]);
  }

  function fmtRefreshTime() {
    const d = new Date();
    const h = String(d.getHours()).padStart(2, "0");
    const m = String(d.getMinutes()).padStart(2, "0");
    const s = String(d.getSeconds()).padStart(2, "0");
    return h + ":" + m + ":" + s;
  }

  async function refreshPage() {
    const btn = $("plan-btn-refresh");
    const status = $("plan-refresh-status");
    if (btn) btn.disabled = true;
    if (status) status.textContent = "刷新中…";
    try {
      await loadMeta();
      await refreshAll();
      if (status) status.textContent = "已刷新 " + fmtRefreshTime();
    } catch (e) {
      toast(e.message || "刷新失败", true);
      if (status) status.textContent = "刷新失败";
    } finally {
      if (btn) btn.disabled = false;
    }
  }

  function readCreateForm() {
    const dir = document.querySelector('input[name="plan-direction"]:checked');
    return {
      plan_date: ($("plan-create-date") && $("plan-create-date").value) || "",
      exchange_key: ($("plan-create-exchange") && $("plan-create-exchange").value) || "",
      symbol: ($("plan-create-symbol") && $("plan-create-symbol").value) || "",
      plan_type: ($("plan-create-type") && $("plan-create-type").value) || "",
      trend_timeframe: ($("plan-create-trend-tf") && $("plan-create-trend-tf").value) || "",
      entry_timeframe: ($("plan-create-entry-tf") && $("plan-create-entry-tf").value) || "",
      direction: (dir && dir.value) || "",
      target_level: ($("plan-create-target") && $("plan-create-target").value) || "",
      current_range: ($("plan-create-range") && $("plan-create-range").value) || "",
      note: ($("plan-create-note") && $("plan-create-note").value) || "",
    };
  }

  function resetCreateForm() {
    const form = $("plan-create-form");
    if (form) form.reset();
    bindMetaToCreateForm();
    if ($("plan-create-date")) $("plan-create-date").value = todayIso();
  }

  function openDetailModal(plan) {
    const modal = $("plan-detail-modal");
    const body = $("plan-detail-body");
    const title = $("plan-detail-title");
    if (!modal || !body || !plan) return;
    if (title) title.textContent = plan.symbol + " · " + (plan.result_label || "计划");
    const rows = [
      ["日期", plan.plan_date],
      ["交易所", exchangeLabel(plan.exchange_key)],
      ["币种", plan.symbol],
      ["类型", plan.plan_type_label],
      ["趋势周期", plan.trend_timeframe],
      ["入场周期", plan.entry_timeframe],
      ["方向", plan.direction_label],
      ["目标位", plan.target_level || "—"],
      ["当前区间", plan.current_range || "—"],
      ["入场方案", plan.entry_scheme_label],
      ["结果", plan.result_label || "—"],
      ["盈亏", fmtPnl(plan.pnl_amount) || "—"],
      ["备注", plan.note || "—"],
    ];
    body.innerHTML = rows
      .map(function (pair) {
        return (
          '<div class="plan-detail-row"><span class="plan-detail-k">' +
          esc(pair[0]) +
          '</span><span class="plan-detail-v">' +
          esc(pair[1]) +
          "</span></div>"
        );
      })
      .join("");
    modal.classList.remove("hidden");
    modal.setAttribute("aria-hidden", "false");
  }

  function closeDetailModal() {
    const modal = $("plan-detail-modal");
    if (!modal) return;
    modal.classList.add("hidden");
    modal.setAttribute("aria-hidden", "true");
  }

  function buildEditFormHtml(p) {
    const dirs = (meta.directions || [])
      .map(function (d) {
        return (
          '<label class="plan-radio-label"><input type="radio" name="edit-direction" value="' +
          esc(d.value) +
          '"' +
          (p.direction === d.value ? " checked" : "") +
          " /> " +
          esc(d.label) +
          "</label>"
        );
      })
      .join("");
    function opts(list, key, valKey, labelKey) {
      return (list || [])
        .map(function (o) {
          const v = typeof o === "string" ? o : o[valKey];
          const lbl = typeof o === "string" ? o : o[labelKey];
          return (
            '<option value="' +
            esc(v) +
            '"' +
            (String(p[key]) === String(v) ? " selected" : "") +
            ">" +
            esc(lbl) +
            "</option>"
          );
        })
        .join("");
    }
    return (
      '<div class="plan-form-grid">' +
      '<label class="plan-field"><span>日期</span><input name="plan_date" type="date" value="' +
      esc(p.plan_date) +
      '" required /></label>' +
      '<label class="plan-field"><span>交易所</span><select name="exchange_key" required>' +
      opts(meta.exchanges, "exchange_key", "key", "name") +
      "</select></label>" +
      '<label class="plan-field"><span>币种</span><input name="symbol" type="text" value="' +
      esc(p.symbol) +
      '" required /></label>' +
      '<label class="plan-field"><span>类型</span><select name="plan_type" required>' +
      opts(meta.plan_types, "plan_type", "value", "label") +
      "</select></label>" +
      '<label class="plan-field"><span>趋势周期</span><select name="trend_timeframe" required>' +
      opts(meta.trend_timeframes, "trend_timeframe") +
      "</select></label>" +
      '<label class="plan-field"><span>入场周期</span><select name="entry_timeframe" required>' +
      opts(meta.entry_timeframes, "entry_timeframe") +
      "</select></label>" +
      '<label class="plan-field plan-field-full"><span>方向</span><span class="plan-radio-row">' +
      dirs +
      "</span></label>" +
      '<label class="plan-field"><span>目标位</span><input name="target_level" type="text" value="' +
      esc(p.target_level || "") +
      '" /></label>' +
      '<label class="plan-field"><span>当前区间</span><input name="current_range" type="text" value="' +
      esc(p.current_range || "") +
      '" /></label>' +
      '<label class="plan-field plan-field-full"><span>入场方案</span><select name="entry_scheme" required>' +
      opts(meta.entry_schemes, "entry_scheme", "value", "label") +
      "</select></label>" +
      '<label class="plan-field plan-field-full"><span>备注</span><textarea name="note" rows="2">' +
      esc(p.note || "") +
      "</textarea></label>" +
      "</div>" +
      '<div class="modal-actions"><button type="button" class="ghost" data-plan-edit-close>取消</button>' +
      '<button type="submit" class="primary">保存修改</button></div>'
    );
  }

  function openEditModal(plan) {
    const modal = $("plan-edit-modal");
    const form = $("plan-edit-form");
    if (!modal || !form || !plan) return;
    editingPlanId = plan.id;
    form.innerHTML = buildEditFormHtml(plan);
    modal.classList.remove("hidden");
    modal.setAttribute("aria-hidden", "false");
  }

  function closeEditModal() {
    const modal = $("plan-edit-modal");
    if (!modal) return;
    editingPlanId = null;
    modal.classList.add("hidden");
    modal.setAttribute("aria-hidden", "true");
  }

  function readEditForm(form) {
    const fd = new FormData(form);
    const dir = form.querySelector('input[name="edit-direction"]:checked');
    return {
      plan_date: fd.get("plan_date") || "",
      exchange_key: fd.get("exchange_key") || "",
      symbol: fd.get("symbol") || "",
      plan_type: fd.get("plan_type") || "",
      trend_timeframe: fd.get("trend_timeframe") || "",
      entry_timeframe: fd.get("entry_timeframe") || "",
      direction: (dir && dir.value) || "",
      target_level: fd.get("target_level") || "",
      current_range: fd.get("current_range") || "",
      entry_scheme: fd.get("entry_scheme") || "",
      note: fd.get("note") || "",
    };
  }

  function bindEvents() {
    const refreshBtn = $("plan-btn-refresh");
    if (refreshBtn) {
      refreshBtn.addEventListener("click", function () {
        void refreshPage();
      });
    }

    const createForm = $("plan-create-form");
    if (createForm) {
      createForm.addEventListener("submit", function (ev) {
        ev.preventDefault();
        api("/api/entry-plans", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(readCreateForm()),
        })
          .then(function () {
            toast("计划已加入进行中");
            resetCreateForm();
            return refreshAll();
          })
          .catch(function (e) {
            toast(e.message || "保存失败", true);
          });
      });
    }

    const activeList = $("plan-active-list");
    if (activeList) {
      activeList.addEventListener("click", function (ev) {
        const t = ev.target;
        if (!(t instanceof HTMLElement)) return;
        const id = t.getAttribute("data-id");
        if (!id) return;
        if (t.classList.contains("plan-btn-del")) {
          if (!window.confirm("确定删除该进行中的计划?")) return;
          api("/api/entry-plans/" + id, { method: "DELETE" })
            .then(function () {
              toast("已删除");
              return refreshAll();
            })
            .catch(function (e) {
              toast(e.message || "删除失败", true);
            });
          return;
        }
        if (t.classList.contains("plan-btn-edit")) {
          const plan = activePlans.find(function (p) {
            return String(p.id) === String(id);
          });
          if (plan) openEditModal(plan);
          return;
        }
        if (t.classList.contains("plan-btn-archive")) {
          const card = t.closest(".plan-active-card");
          const resultEl = card && card.querySelector('.plan-close-result[data-id="' + id + '"]');
          const pnlEl = card && card.querySelector('.plan-close-pnl[data-id="' + id + '"]');
          const schemeEl = card && card.querySelector('.plan-active-scheme[data-id="' + id + '"]');
          const result = resultEl && resultEl.value;
          if (!result) {
            toast("请先选择结果(盈/亏)", true);
            return;
          }
          const scheme = schemeEl && schemeEl.value;
          if (!scheme) {
            toast("请先选择入场方案(根据实际进场填写)", true);
            return;
          }
          const payload = { result: result, entry_scheme: scheme };
          const pnlRaw = pnlEl && pnlEl.value;
          if (pnlRaw !== "" && pnlRaw != null) payload.pnl_amount = Number(pnlRaw);
          api("/api/entry-plans/" + id, {
            method: "PATCH",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify(payload),
          })
            .then(function () {
              toast("已归档");
              return refreshAll();
            })
            .catch(function (e) {
              toast(e.message || "归档失败", true);
            });
        }
      });

      activeList.addEventListener("change", function (ev) {
        const t = ev.target;
        if (!(t instanceof HTMLElement) || !t.classList.contains("plan-active-scheme")) return;
        const id = t.getAttribute("data-id");
        const scheme = t.value;
        if (!id || !scheme) return;
        api("/api/entry-plans/" + id, {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ entry_scheme: scheme }),
        })
          .then(function () {
            toast("入场方案已保存");
            return loadActive();
          })
          .catch(function (e) {
            toast(e.message || "保存失败", true);
          });
      });
    }

    const historyList = $("plan-history-list");
    if (historyList) {
      historyList.addEventListener("click", function (ev) {
        const row = ev.target.closest(".plan-history-row");
        if (!row) return;
        const id = row.getAttribute("data-id");
        const plan = archivedPlans.find(function (p) {
          return String(p.id) === String(id);
        });
        if (plan) openDetailModal(plan);
        else {
          api("/api/entry-plans/" + id).then(function (data) {
            openDetailModal(data.plan);
          });
        }
      });
    }

    document.querySelectorAll("[data-plan-modal-close]").forEach(function (el) {
      el.addEventListener("click", closeDetailModal);
    });
    document.querySelectorAll("[data-plan-edit-close]").forEach(function (el) {
      el.addEventListener("click", closeEditModal);
    });

    const editForm = $("plan-edit-form");
    if (editForm) {
      editForm.addEventListener("submit", function (ev) {
        ev.preventDefault();
        if (!editingPlanId) return;
        api("/api/entry-plans/" + editingPlanId, {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(readEditForm(editForm)),
        })
          .then(function () {
            toast("已保存");
            closeEditModal();
            return refreshAll();
          })
          .catch(function (e) {
            toast(e.message || "保存失败", true);
          });
      });
    }

    const periodTabs = $("plan-stats-period-tabs");
    if (periodTabs) {
      periodTabs.addEventListener("click", function (ev) {
        const btn = ev.target.closest(".plan-period-btn");
        if (!btn) return;
        statsPeriod = btn.getAttribute("data-period") || "all";
        periodTabs.querySelectorAll(".plan-period-btn").forEach(function (b) {
          b.classList.toggle("is-active", b === btn);
        });
        const rangeWrap = $("plan-stats-range-wrap");
        if (rangeWrap) rangeWrap.classList.toggle("hidden", statsPeriod !== "range");
        loadStats().catch(function (e) {
          toast(e.message || "统计加载失败", true);
        });
      });
    }

    const dimTabs = $("plan-stats-dim-tabs");
    if (dimTabs) {
      dimTabs.addEventListener("click", function (ev) {
        const btn = ev.target.closest(".plan-dim-btn");
        if (!btn) return;
        statsDim = btn.getAttribute("data-dim") || "symbol";
        dimTabs.querySelectorAll(".plan-dim-btn").forEach(function (b) {
          b.classList.toggle("is-active", b === btn);
        });
        loadStats().catch(function (e) {
          toast(e.message || "统计加载失败", true);
        });
      });
    }

    ["plan-stats-date-from", "plan-stats-date-to"].forEach(function (id) {
      const el = $(id);
      if (!el) return;
      el.addEventListener("change", function () {
        statsDateFrom = ($("plan-stats-date-from") && $("plan-stats-date-from").value) || "";
        statsDateTo = ($("plan-stats-date-to") && $("plan-stats-date-to").value) || "";
        if (statsPeriod === "range") {
          loadStats().catch(function (e) {
            toast(e.message || "统计加载失败", true);
          });
        }
      });
    });
  }

  async function init() {
    if (inited) {
      await refreshPage();
      return;
    }
    inited = true;
    bindEvents();
    try {
      await loadMeta();
      await refreshAll();
      const status = $("plan-refresh-status");
      if (status) status.textContent = "已刷新 " + fmtRefreshTime();
    } catch (e) {
      toast(e.message || "加载失败", true);
    }
  }

  function destroy() {}

  window.hubPlanPage = { init: init, refresh: refreshPage, destroy: destroy };
})();
