/**
 * 中控资金概况:总资金曲线,分户资金与回撤(资金户+交易户,不含浮盈).
 */
(function () {
  const page = document.getElementById("page-funds");
  if (!page) return;

  const elStatus = document.getElementById("funds-status");
  const elTotal = document.getElementById("funds-total-usdt");
  const elDdU = document.getElementById("funds-total-dd-u");
  const elDdPct = document.getElementById("funds-total-dd-pct");
  const elDelta = document.getElementById("funds-total-delta");
  const elPeriod = document.getElementById("funds-total-period");
  const elPeriodSub = document.getElementById("funds-total-period-sub");
  const elPeriodBanner = document.getElementById("funds-period-delta");
  const elPeriodPct = document.getElementById("funds-period-pct");
  const elDayChip = document.getElementById("funds-day-chip");
  const elPnlBanner = document.getElementById("funds-pnl-banner");
  const elMeta = document.getElementById("funds-meta");
  const elDescBody = document.getElementById("funds-desc-body");
  const elChartSub = document.getElementById("funds-chart-sub");
  const elChartHost = document.getElementById("funds-chart-total");
  const elAccounts = document.getElementById("funds-accounts");
  const elBtnRefresh = document.getElementById("funds-btn-refresh");

  const elFs = document.getElementById("funds-fullscreen");
  const elFsBackdrop = document.getElementById("funds-fs-backdrop");
  const elFsClose = document.getElementById("funds-fs-close");
  const elFsTitle = document.getElementById("funds-fs-title");
  const elFsSub = document.getElementById("funds-fs-sub");
  const elFsTotal = document.getElementById("funds-fs-total");
  const elFsFunding = document.getElementById("funds-fs-funding");
  const elFsTrading = document.getElementById("funds-fs-trading");
  const elFsDelta = document.getElementById("funds-fs-delta");
  const elFsDd = document.getElementById("funds-fs-dd");
  const elFsChartHost = document.getElementById("funds-fs-chart");

  let chart = null;
  let lineSeries = null;
  let fsChart = null;
  let fsLineSeries = null;
  let inited = false;
  let loading = false;
  let lastOverview = null;
  let fsAccountKey = "";

  function fmt(n, d) {
    if (n == null || n === "" || !Number.isFinite(Number(n))) return "—";
    return Number(n).toFixed(d == null ? 2 : d);
  }

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

  function fmtPct(n) {
    if (n == null || !Number.isFinite(Number(n))) return "—";
    const v = Number(n);
    const sign = v > 0 ? "+" : "";
    return sign + v.toFixed(2) + "%";
  }

  function deltaClass(n) {
    if (!Number.isFinite(Number(n))) return "";
    if (Number(n) > 0) return "pos";
    if (Number(n) < 0) return "neg";
    return "";
  }

  function setStatus(msg, isErr) {
    if (!elStatus) return;
    elStatus.textContent = msg || "";
    elStatus.className = "funds-status" + (isErr ? " err" : "");
  }

  function seriesToChartData(series) {
    return (series || [])
      .filter(function (p) {
        return p && p.day && Number.isFinite(Number(p.total_usdt));
      })
      .map(function (p) {
        return { time: String(p.day), value: Number(p.total_usdt) };
      });
  }

  function destroyChart() {
    if (chart) {
      chart.remove();
      chart = null;
      lineSeries = null;
    }
    if (elChartHost) elChartHost.innerHTML = "";
  }

  function destroyFsChart() {
    if (fsChart) {
      fsChart.remove();
      fsChart = null;
      fsLineSeries = null;
    }
    if (elFsChartHost) elFsChartHost.innerHTML = "";
  }

  function chartPalette() {
    const light = document.documentElement.getAttribute("data-theme") === "light";
    return light
      ? { bg: "#eef4fa", text: "#4a6078", border: "#c5d4e4", line: "#006e9a", top: "#006e9a44" }
      : { bg: "#060a14", text: "#6b8aa8", border: "#1a2840", line: "#00d4ff", top: "#00d4ff55" };
  }

  function createAreaChart(host) {
    const p = chartPalette();
    const c = LightweightCharts.createChart(host, {
      layout: {
        background: { color: p.bg },
        textColor: p.text,
        fontSize: 11,
      },
      grid: {
        vertLines: { color: p.border, visible: true },
        horzLines: { color: p.border, visible: true },
      },
      rightPriceScale: {
        borderColor: p.border,
        scaleMargins: { top: 0.08, bottom: 0.08 },
      },
      timeScale: {
        borderColor: p.border,
        timeVisible: true,
        fixLeftEdge: true,
        fixRightEdge: true,
      },
      crosshair: { mode: LightweightCharts.CrosshairMode.Normal },
      handleScroll: { mouseWheel: true, pressedMouseMove: true },
      handleScale: { axisPressedMouseMove: true, mouseWheel: true, pinch: true },
    });
    const s = c.addAreaSeries({
      lineColor: p.line,
      topColor: p.top || p.line + "44",
      bottomColor: p.line + "08",
      lineWidth: 2,
      priceFormat: { type: "price", precision: 2, minMove: 0.01 },
    });
    function syncSize() {
      if (!c || !host) return;
      const w = Math.max(host.clientWidth || 0, 1);
      const h = Math.max(host.clientHeight || 0, 200);
      c.applyOptions({ width: w, height: h });
    }
    new ResizeObserver(function () {
      syncSize();
    }).observe(host);
    syncSize();
    return { chart: c, series: s };
  }

  function ensureChart() {
    if (!elChartHost || !window.LightweightCharts) return;
    if (chart) return;
    const built = createAreaChart(elChartHost);
    chart = built.chart;
    lineSeries = built.series;
  }

  function ensureFsChart() {
    if (!elFsChartHost || !window.LightweightCharts) return;
    if (fsChart) return;
    const built = createAreaChart(elFsChartHost);
    fsChart = built.chart;
    fsLineSeries = built.series;
  }

  function esc(s) {
    return String(s || "")
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/"/g, "&quot;");
  }

  function accountStatus(ac) {
    if (!ac || !ac.monitored) return { text: "未监控", cls: "" };
    if (ac.data_ok) return { text: "已监控", cls: "is-ok" };
    return { text: "余额未齐", cls: "" };
  }

  function renderAccounts(accounts) {
    if (!elAccounts) return;
    if (!accounts || !accounts.length) {
      elAccounts.innerHTML = '<p class="funds-empty">暂无账户配置</p>';
      return;
    }
    elAccounts.innerHTML = accounts
      .map(function (ac) {
        const monitored = !!ac.monitored;
        const offCls = monitored ? "" : " is-off";
        const st = accountStatus(ac);
        const clickable = monitored ? "" : ' disabled aria-disabled="true"';
        const name = ac.name || ac.key || "—";
        const total =
          monitored && ac.data_ok ? fmt(ac.total_usdt, 2) + " U" : "—";
        const funding =
          monitored && ac.funding_usdt != null ? fmt(ac.funding_usdt, 2) + " U" : "—";
        const trading =
          monitored && ac.trading_usdt != null ? fmt(ac.trading_usdt, 2) + " U" : "—";
        const optFunding =
          monitored && ac.options_funding_usdt != null ? fmt(ac.options_funding_usdt, 2) + " U" : "";
        const optTrading =
          monitored && ac.options_trading_usdt != null ? fmt(ac.options_trading_usdt, 2) + " U" : "";
        const optLine =
          optFunding || optTrading
            ? '<div><span class="k">期权户</span><span class="v">' +
              (optFunding || "—") +
              " / " +
              (optTrading || "—") +
              "</span></div>"
            : "";
        const dd = ac.drawdown || {};
        const ddU = dd.max_drawdown_u != null ? fmt(dd.max_drawdown_u, 2) + " U" : "—";
        const ddPct = dd.max_drawdown_pct != null ? fmt(dd.max_drawdown_pct, 2) + "%" : "—";
        const deltaCls = deltaClass(ac.day_delta_usdt);
        const deltaText = monitored ? fmtDelta(ac.day_delta_usdt) : "—";
        const periodCls = deltaClass(ac.period_delta_usdt);
        const periodText = monitored ? fmtDelta(ac.period_delta_usdt) : "—";
        return (
          '<button type="button" class="funds-ac-card' +
          offCls +
          '" data-key="' +
          esc(ac.key || "") +
          '"' +
          clickable +
          ' title="' +
          esc(monitored ? "点击查看 " + name + " 资金曲线" : "未监控,不参与合计") +
          '">' +
          '<div class="funds-ac-head">' +
          '<h3 class="funds-ac-name">' +
          esc(name) +
          "</h3>" +
          '<span class="funds-ac-badge ' +
          st.cls +
          '">' +
          st.text +
          "</span>" +
          "</div>" +
          '<div class="funds-ac-total">' +
          '<span class="k">总资金</span>' +
          '<span class="v">' +
          total +
          "</span>" +
          "</div>" +
          '<div class="funds-ac-stats">' +
          '<div><span class="k">资金户</span><span class="v">' +
          funding +
          "</span></div>" +
          '<div><span class="k">交易户</span><span class="v">' +
          trading +
          "</span></div>" +
          optLine +
          '<div><span class="k">累计盈亏</span><span class="v ' +
          periodCls +
          '">' +
          periodText +
          "</span></div>" +
          '<div><span class="k">较昨日</span><span class="v ' +
          deltaCls +
          '">' +
          deltaText +
          "</span></div>" +
          '<div><span class="k">最大回撤</span><span class="v">' +
          ddU +
          " / " +
          ddPct +
          "</span></div>" +
          "</div>" +
          (monitored
            ? '<div class="funds-ac-foot">点击查看资金曲线</div>'
            : "") +
          "</button>"
        );
      })
      .join("");

    elAccounts.querySelectorAll(".funds-ac-card:not(.is-off)").forEach(function (btn) {
      btn.addEventListener("click", function () {
        openAccountFullscreen(btn.getAttribute("data-key"));
      });
    });
  }

  function findAccount(key) {
    const accounts = (lastOverview && lastOverview.accounts) || [];
    return accounts.find(function (ac) {
      return String(ac.key || "") === String(key || "");
    });
  }

  function closeAccountFullscreen() {
    fsAccountKey = "";
    destroyFsChart();
    if (elFs) {
      elFs.classList.add("hidden");
      elFs.setAttribute("aria-hidden", "true");
    }
    document.body.classList.remove("funds-fullscreen-open");
  }

  function openAccountFullscreen(key) {
    const ac = findAccount(key);
    if (!ac || !ac.monitored) return;
    fsAccountKey = String(key || "");
    const dd = ac.drawdown || {};
    const meta = lastOverview || {};
    if (elFsTitle) elFsTitle.textContent = ac.name || ac.key || "—";
    if (elFsSub) {
      const parts = [
        "资金户 + 交易户 + 期权户(USDC≈USDT,不含浮盈)",
        "交易日 " + (meta.trading_day || "—"),
        "自 " + (meta.history_start_day || "—") + " 起",
      ];
      elFsSub.textContent = parts.join(" · ");
    }
    if (elFsTotal) {
      elFsTotal.textContent =
        ac.data_ok && ac.total_usdt != null ? fmt(ac.total_usdt, 2) + " U" : "—";
    }
    if (elFsFunding) {
      elFsFunding.textContent =
        ac.funding_usdt != null ? fmt(ac.funding_usdt, 2) + " U" : "—";
    }
    if (elFsTrading) {
      elFsTrading.textContent =
        ac.trading_usdt != null ? fmt(ac.trading_usdt, 2) + " U" : "—";
    }
    if (elFsDelta) {
      elFsDelta.textContent = fmtDelta(ac.day_delta_usdt);
      elFsDelta.className = "v " + deltaClass(ac.day_delta_usdt);
    }
    if (elFsDd) {
      const ddU = dd.max_drawdown_u != null ? fmt(dd.max_drawdown_u, 2) + " U" : "—";
      const ddPct = dd.max_drawdown_pct != null ? fmt(dd.max_drawdown_pct, 2) + "%" : "—";
      elFsDd.textContent = ddU + " / " + ddPct;
    }
    if (elFs) {
      elFs.classList.remove("hidden");
      elFs.setAttribute("aria-hidden", "false");
      document.body.classList.add("funds-fullscreen-open");
    }
    destroyFsChart();
    const pts = seriesToChartData(ac.series || []);
    if (pts.length) {
      ensureFsChart();
      if (fsLineSeries) {
        fsLineSeries.setData(pts);
        fsChart.timeScale().fitContent();
      }
      requestAnimationFrame(function () {
        if (fsChart && elFsChartHost) {
          fsChart.applyOptions({
            width: elFsChartHost.clientWidth,
            height: elFsChartHost.clientHeight,
          });
          fsChart.timeScale().fitContent();
        }
      });
    } else if (elFsChartHost) {
      elFsChartHost.innerHTML =
        '<p class="funds-empty">暂无历史曲线,请保持监控板运行以积累快照</p>';
    }
  }

  function renderDesc(data) {
    const start = (data && data.history_start_day) || "—";
    const keep = (data && data.keep_days) || 180;
    const hour = data && data.reset_hour != null ? data.reset_hour : 8;
    if (elDescBody) {
      elDescBody.textContent =
        "总资金 = 各监控户(永续资金账户 + 交易账户 + 期权账户,USDC 按 1:1 计入 USDT);自 " +
        start +
        " 起按北京时间 " +
        hour +
        ":00 交易日切日快照,最多保留 " +
        keep +
        " 天.起算日由环境变量 HUB_FUND_HISTORY_START_DAY 配置.";
    }
    if (elChartSub) {
      elChartSub.textContent = keep + " TRADING DAYS";
    }
  }

  function renderOverview(data) {
    lastOverview = data;
    renderDesc(data);
    const totals = data.totals || {};
    const dd = totals.drawdown || {};
    if (elTotal) {
      elTotal.textContent =
        totals.total_usdt != null ? fmt(totals.total_usdt, 2) + " U" : "—";
    }
    if (elDdU) elDdU.textContent = dd.max_drawdown_u != null ? fmt(dd.max_drawdown_u, 2) + " U" : "—";
    if (elDdPct) {
      elDdPct.textContent = dd.max_drawdown_pct != null ? fmt(dd.max_drawdown_pct, 2) + "%" : "—";
    }
    if (elDelta) {
      elDelta.textContent = fmtDelta(totals.day_delta_usdt);
      elDelta.className = "funds-stat-val " + deltaClass(totals.day_delta_usdt);
    }
    const periodCls = deltaClass(totals.period_delta_usdt);
    if (elPeriod) {
      elPeriod.textContent = fmtDelta(totals.period_delta_usdt);
      elPeriod.className = "funds-stat-val " + periodCls;
    }
    if (elPeriodSub) {
      const startDay = data.history_start_day || "—";
      const pct = fmtPct(totals.period_delta_pct);
      elPeriodSub.textContent =
        pct !== "—"
          ? "自 " + startDay + " · " + pct
          : "自 " + startDay + " 起相对起点";
    }
    if (elPeriodBanner) {
      elPeriodBanner.textContent = fmtDelta(totals.period_delta_usdt);
      elPeriodBanner.className = "funds-pnl-value " + periodCls;
    }
    if (elPeriodPct) {
      elPeriodPct.textContent = fmtPct(totals.period_delta_pct);
      elPeriodPct.className = "funds-pnl-pct " + periodCls;
    }
    if (elDayChip) {
      elDayChip.textContent = fmtDelta(totals.day_delta_usdt);
      elDayChip.className = "funds-pnl-side-val " + deltaClass(totals.day_delta_usdt);
    }
    if (elPnlBanner) {
      elPnlBanner.className =
        "funds-pnl-banner" + (periodCls ? " is-" + periodCls : "");
    }
    if (elMeta) {
      const parts = [
        "交易日 " + (data.trading_day || "—"),
        "切日 " + (data.reset_hour != null ? data.reset_hour : 8) + ":00 北京",
        "自 " + (data.history_start_day || "—") + " 起",
        "最多 " + (data.keep_days || 180) + " 交易日",
      ];
      if (data.updated_at) parts.push("刷新 " + data.updated_at);
      if (totals.live_known_count != null) {
        parts.push("合计含 " + totals.live_known_count + " 户");
      }
      elMeta.textContent = parts.join(" · ");
    }
    ensureChart();
    if (lineSeries) {
      const pts = seriesToChartData(totals.series || []);
      if (pts.length) {
        lineSeries.setData(pts);
        chart.timeScale().fitContent();
      } else {
        lineSeries.setData([]);
      }
    }
    renderAccounts(data.accounts || []);
    // 分户卡片渲染后高度会变,补一次尺寸,避免 1080p 一屏布局下曲线被裁切
    if (chart && elChartHost) {
      requestAnimationFrame(function () {
        if (!chart || !elChartHost) return;
        chart.applyOptions({
          width: Math.max(elChartHost.clientWidth || 0, 1),
          height: Math.max(elChartHost.clientHeight || 0, 200),
        });
        chart.timeScale().fitContent();
      });
    }
    if (fsAccountKey) {
      const ac = findAccount(fsAccountKey);
      if (ac && ac.monitored) openAccountFullscreen(fsAccountKey);
      else closeAccountFullscreen();
    }
  }

  async function load() {
    if (loading) return;
    loading = true;
    setStatus("加载中…");
    try {
      const r = await fetch("/api/hub/fund-overview", { credentials: "same-origin" });
      const j = await r.json();
      if (!r.ok) {
        setStatus(j.detail || j.msg || "加载失败", true);
        return;
      }
      renderOverview(j);
      setStatus("");
    } catch (e) {
      setStatus(String(e.message || e), true);
    } finally {
      loading = false;
    }
  }

  function bind() {
    if (elBtnRefresh) elBtnRefresh.addEventListener("click", load);
    if (elFsBackdrop) elFsBackdrop.addEventListener("click", closeAccountFullscreen);
    if (elFsClose) elFsClose.addEventListener("click", closeAccountFullscreen);
    document.addEventListener("keydown", function (ev) {
      if (ev.key === "Escape" && fsAccountKey) closeAccountFullscreen();
    });
    document.addEventListener("hub-theme-change", function () {
      destroyChart();
      destroyFsChart();
      load();
    });
  }

  function init() {
    if (!page || page.classList.contains("hidden")) return;
    if (!inited) {
      bind();
      inited = true;
    }
    load();
  }

  function destroy() {
    closeAccountFullscreen();
    destroyChart();
  }

  window.hubFundsPage = { init: init, destroy: destroy, reload: load };
})();
