/**
 * 三所 /records:交易记录分页 + 复盘表单显隐 + 复盘/AI 列表分页(soft,每页5).
 */
(function (global) {
  "use strict";

  var PAGE_SIZE = 5;
  var tradesPage = 0;
  var tradesPages = 1;
  var journalsAll = [];
  var journalsPage = 0;
  var journalsPages = 1;
  var reviewsAll = [];
  var reviewsPage = 0;
  var reviewsPages = 1;
  var tradesCache = {};
  var booted = 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 listQs() {
    if (typeof global.listWindowQueryString === "function") {
      return global.listWindowQueryString() || "";
    }
    return "";
  }

  function fmtNum(v, digits) {
    if (v == null || v === "") return "—";
    var n = Number(v);
    if (!Number.isFinite(n)) return esc(v);
    return n.toFixed(digits == null ? 2 : digits);
  }

  function fmtTime(s) {
    if (!s) return "—";
    return esc(String(s).slice(0, 16));
  }

  function resultBadge(result) {
    var er = String(result || "").trim();
    if (["止盈", "保本止盈", "移动止盈"].indexOf(er) >= 0) {
      return '<span class="badge profit">' + esc(er) + "</span>";
    }
    if (["止损", "强制清仓", "手动平仓"].indexOf(er) >= 0) {
      return '<span class="badge loss">' + esc(er) + "</span>";
    }
    if (er === "时间平仓") return '<span class="badge miss">' + esc(er) + "</span>";
    return '<span class="badge">' + esc(er || "-") + "</span>";
  }

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

  function beginSoft(wrapId, soft) {
    var wrap = $(wrapId);
    if (!wrap) return null;
    if (soft) {
      if (!wrap.style.minHeight) {
        wrap.style.minHeight = Math.max(wrap.offsetHeight, 1) + "px";
      }
      wrap.classList.add("rr-list-loading");
    } else {
      wrap.classList.remove("rr-list-loading");
      wrap.style.minHeight = "";
    }
    return wrap;
  }

  function endSoft(wrap) {
    if (!wrap) return;
    wrap.classList.remove("rr-list-loading");
    wrap.style.minHeight = "";
  }

  function updatePager(kind) {
    var map = {
      trades: {
        page: tradesPage,
        pages: tradesPages,
        label: "rr-trades-page-label",
        prev: "rr-trades-prev",
        next: "rr-trades-next",
      },
      journals: {
        page: journalsPage,
        pages: journalsPages,
        label: "rr-journals-page-label",
        prev: "rr-journals-prev",
        next: "rr-journals-next",
      },
      reviews: {
        page: reviewsPage,
        pages: reviewsPages,
        label: "rr-reviews-page-label",
        prev: "rr-reviews-prev",
        next: "rr-reviews-next",
      },
    };
    var m = map[kind];
    if (!m) return;
    var label = $(m.label);
    var prev = $(m.prev);
    var next = $(m.next);
    if (label) label.textContent = "第 " + (m.page + 1) + " / " + m.pages + " 页";
    if (prev) prev.disabled = m.page <= 0;
    if (next) next.disabled = m.page + 1 >= m.pages;
  }

  function fillPayload(t) {
    return {
      symbol: t.symbol,
      monitor_type: t.monitor_type,
      key_signal_type: t.key_signal_type || "",
      direction: t.direction,
      trigger_price: t.trigger_price,
      stop_loss: t.display_open_stop_loss || t.initial_stop_loss || t.stop_loss,
      take_profit: t.effective_take_profit || t.take_profit,
      opened_at: t.effective_opened_at,
      closed_at: t.effective_closed_at,
      pnl_amount: t.effective_pnl_amount,
      result: t.effective_result,
      risk_amount: t.risk_amount,
      effective_entry_reason: t.effective_entry_reason || "",
    };
  }

  function editPayload(t) {
    return {
      id: t.id,
      opened_at: t.effective_opened_at,
      closed_at: t.effective_closed_at,
      stop_loss: t.effective_stop_loss || t.initial_stop_loss || t.stop_loss,
      take_profit: t.effective_take_profit || t.take_profit,
      pnl_amount: t.effective_pnl_amount,
      result: t.effective_result,
      miss_reason: t.effective_miss_reason,
      effective_entry_reason: t.effective_entry_reason || "",
    };
  }

  function renderTradesRows(rows) {
    var tbody = $("rr-trades-tbody");
    if (!tbody) return;
    tradesCache = {};
    if (!rows || !rows.length) {
      tbody.innerHTML = '<tr><td colspan="15" class="muted">暂无交易记录</td></tr>';
      return;
    }
    tbody.innerHTML = rows
      .map(function (t) {
        tradesCache[t.id] = t;
        var mon = esc(t.monitor_type || "");
        if (t.key_signal_type) mon += " · " + esc(t.key_signal_type);
        var stopShow = t.display_open_stop_loss || t.initial_stop_loss || t.stop_loss;
        var tpShow = t.effective_take_profit || t.take_profit;
        var pnl = t.effective_pnl_amount;
        var pnlSrc = "";
        if (t.display_pnl_source === "exchange") {
          pnlSrc = '<span style="font-size:.68rem;color:#6ab88a">所</span>';
        } else if (t.display_pnl_source !== "reviewed") {
          pnlSrc = '<span style="font-size:.68rem;color:#8892b0">估</span>';
        }
        var dirCls = t.direction === "long" ? "direction-long" : "direction-short";
        var dirTxt = t.direction === "long" ? "做多" : "做空";
        var margin =
          t.margin_capital != null && t.margin_capital !== ""
            ? fmtNum(t.margin_capital, 2)
            : "-";
        return (
          '<tr id="trade-row-' +
          esc(t.id) +
          '">' +
          "<td>" +
          esc(t.symbol) +
          "</td>" +
          "<td>" +
          mon +
          "</td>" +
          "<td>" +
          esc(t.effective_entry_reason || "-") +
          "</td>" +
          '<td><span class="badge ' +
          dirCls +
          '">' +
          dirTxt +
          "</span></td>" +
          "<td>" +
          fmtNum(t.trigger_price, 4) +
          "</td>" +
          "<td>" +
          fmtNum(stopShow, 4) +
          "</td>" +
          "<td>" +
          fmtNum(tpShow, 4) +
          "</td>" +
          "<td>" +
          margin +
          "</td>" +
          "<td>" +
          esc(t.leverage != null ? t.leverage : "-") +
          "</td>" +
          "<td>" +
          esc(t.effective_hold_minutes || 0) +
          "</td>" +
          "<td>" +
          fmtTime(t.effective_opened_at) +
          "</td>" +
          "<td>" +
          fmtTime(t.effective_closed_at || t.created_at) +
          "</td>" +
          '<td><span class="' +
          pnlClass(pnl) +
          '">' +
          fmtNum(pnl, 2) +
          "</span>" +
          pnlSrc +
          "</td>" +
          "<td>" +
          resultBadge(t.effective_result) +
          "</td>" +
          "<td>" +
          '<button type="button" class="table-del rr-fill-btn" style="background:#1f3a5a;color:#8fc8ff;margin-right:6px" data-id="' +
          esc(t.id) +
          '">填入复盘</button> ' +
          '<button type="button" class="table-del review-edit-btn" style="background:#1f3a5a;color:#8fc8ff;margin-right:6px" data-id="' +
          esc(t.id) +
          '" disabled>核对修改</button> ' +
          '<button type="button" class="table-del" onclick="deleteTradeRecord(' +
          Number(t.id) +
          ')">删除</button>' +
          "</td>" +
          "</tr>"
        );
      })
      .join("");

    tbody.querySelectorAll(".rr-fill-btn").forEach(function (btn) {
      btn.addEventListener("click", function () {
        var id = btn.getAttribute("data-id");
        var t = tradesCache[id];
        if (!t) return;
        showJournalCard();
        if (typeof global.fillJournalFromTrade === "function") {
          global.fillJournalFromTrade(fillPayload(t));
        }
      });
    });
    tbody.querySelectorAll(".review-edit-btn").forEach(function (btn) {
      btn.addEventListener("click", function () {
        var id = btn.getAttribute("data-id");
        var t = tradesCache[id];
        if (!t) return;
        if (typeof global.editTradeRecordReview === "function") {
          global.editTradeRecordReview(editPayload(t));
        }
      });
    });
    if (typeof global.toggleReviewMode === "function") {
      global.toggleReviewMode();
    }
  }

  function loadTradeRecords(opts) {
    opts = opts || {};
    var soft = !!opts.soft;
    var tbody = $("rr-trades-tbody");
    if (!tbody) return;
    var wrap = beginSoft("rr-trades-wrap", soft);
    if (!soft) {
      tbody.innerHTML = '<tr><td colspan="15" class="muted">加载中…</td></tr>';
    }
    var qs = listQs();
    var p = new URLSearchParams(qs || "");
    p.set("limit", String(PAGE_SIZE));
    p.set("offset", String(tradesPage * PAGE_SIZE));
    fetch("/api/trade_records?" + p.toString(), { credentials: "same-origin" })
      .then(function (r) {
        return r.json();
      })
      .then(function (data) {
        if (!data || !data.ok) {
          tbody.innerHTML = '<tr><td colspan="15" class="muted">加载失败</td></tr>';
          endSoft(wrap);
          return;
        }
        tradesPages = Math.max(1, Number(data.pages) || 1);
        if (tradesPage >= tradesPages) {
          tradesPage = Math.max(0, tradesPages - 1);
          updatePager("trades");
          if (Number(data.total || 0) > 0) {
            loadTradeRecords(opts);
            return;
          }
        }
        updatePager("trades");
        renderTradesRows(data.items || []);
        endSoft(wrap);
      })
      .catch(function () {
        tbody.innerHTML = '<tr><td colspan="15" class="muted">加载失败</td></tr>';
        endSoft(wrap);
      });
  }

  function renderJournalsPage(soft) {
    var box = $("journal-list");
    if (!box) return;
    var wrap = beginSoft("journal-list-wrap", soft);
    var total = journalsAll.length;
    journalsPages = Math.max(1, Math.ceil(total / PAGE_SIZE) || 1);
    if (journalsPage >= journalsPages) journalsPage = Math.max(0, journalsPages - 1);
    updatePager("journals");
    var hint = $("rr-journals-hint");
    if (hint) {
      hint.textContent =
        total > 0
          ? "已保存的复盘(共" + total + "条,每页5条)."
          : "已保存的复盘(每页5条).";
    }
    var slice = journalsAll.slice(
      journalsPage * PAGE_SIZE,
      journalsPage * PAGE_SIZE + PAGE_SIZE
    );
    if (global.InstanceUI && typeof InstanceUI.renderJournalListHtml === "function") {
      var html = InstanceUI.renderJournalListHtml(slice);
      box.innerHTML = html || "<div class='journal-empty-msg'>暂无数据</div>";
    } else {
      box.innerHTML = "<div class='journal-empty-msg'>暂无数据</div>";
    }
    endSoft(wrap);
  }

  function renderReviewsPage(soft) {
    var box = $("review-list");
    if (!box) return;
    var wrap = beginSoft("review-list-wrap", soft);
    var total = reviewsAll.length;
    reviewsPages = Math.max(1, Math.ceil(total / PAGE_SIZE) || 1);
    if (reviewsPage >= reviewsPages) reviewsPage = Math.max(0, reviewsPages - 1);
    updatePager("reviews");
    var slice = reviewsAll.slice(
      reviewsPage * PAGE_SIZE,
      reviewsPage * PAGE_SIZE + PAGE_SIZE
    );
    if (!slice.length) {
      box.innerHTML = "<div class='entry'>暂无数据</div>";
      endSoft(wrap);
      return;
    }
    var html = "";
    slice.forEach(function (r) {
      if (global.reviewCache) global.reviewCache[r.id] = r;
      var preview = (r.content || "").replace(/\s+/g, " ").trim();
      var shortText = preview.length > 90 ? preview.slice(0, 90) + "..." : preview;
      html +=
        '<div class="entry">' +
        "<div><strong>" +
        (r.review_type === "daily" ? "日复盘" : "周复盘") +
        "</strong> | " +
        esc(r.target_date) +
        "</div>" +
        '<div style="font-size:12px;color:#9aa">' +
        esc(r.created_at || "") +
        "</div>" +
        '<div style="margin-top:4px;color:#c9d2ff">' +
        esc(shortText || "(空)") +
        "</div>" +
        '<div style="display:flex;gap:8px;flex-wrap:wrap;margin-top:6px">' +
        '<button type="button" class="btn-del" style="border:none;cursor:pointer;background:#1f3a5a;color:#8fc8ff" onclick="openReviewDetail(\'' +
        esc(r.id) +
        "', false)\">查看</button>" +
        '<button type="button" class="btn-del" style="border:none;cursor:pointer;background:#1f3a5a;color:#8fc8ff" onclick="openReviewDetail(\'' +
        esc(r.id) +
        "', true)\">全屏</button>" +
        '<a class="btn-del" style="text-decoration:none;background:#1f3a5a;color:#8fc8ff" href="/export/review_md/' +
        esc(r.id) +
        '">导出MD</a>' +
        '<button type="button" class="btn-del" onclick="deleteReview(\'' +
        esc(r.id) +
        "')\">删除</button>" +
        "</div></div>";
    });
    box.innerHTML = html;
    endSoft(wrap);
  }

  function loadJournalsPaged() {
    var qs = listQs();
    fetch("/api/journals" + (qs ? "?" + qs : ""), { credentials: "same-origin" })
      .then(function (r) {
        return r.json();
      })
      .then(function (data) {
        journalsAll = Array.isArray(data) ? data : [];
        if (global.journalCache) {
          Object.keys(global.journalCache).forEach(function (k) {
            delete global.journalCache[k];
          });
          journalsAll.forEach(function (o) {
            global.journalCache[o.id] = o;
          });
        }
        journalsPage = 0;
        renderJournalsPage(false);
      });
  }

  function loadReviewsPaged() {
    var qs = listQs();
    fetch("/api/reviews" + (qs ? "?" + qs : ""), { credentials: "same-origin" })
      .then(function (r) {
        return r.json();
      })
      .then(function (data) {
        reviewsAll = Array.isArray(data) ? data : [];
        if (global.reviewCache) {
          Object.keys(global.reviewCache).forEach(function (k) {
            delete global.reviewCache[k];
          });
        } else {
          global.reviewCache = {};
        }
        reviewsAll.forEach(function (r) {
          global.reviewCache[r.id] = r;
        });
        reviewsPage = 0;
        renderReviewsPage(false);
      });
  }

  function showJournalCard() {
    var card = $("journal-card");
    if (card) card.classList.remove("hidden");
    var hint = $("rr-journal-fill-hint");
    if (hint) hint.style.display = "";
  }

  function hideJournalCard() {
    var card = $("journal-card");
    if (card) card.classList.add("hidden");
    var hint = $("rr-journal-fill-hint");
    if (hint) hint.style.display = "none";
  }

  function patchFillJournalFromTrade() {
    var prev = global.fillJournalFromTrade;
    if (typeof prev !== "function") return;
    if (prev.__rrPatched) return;
    global.fillJournalFromTrade = function (t) {
      showJournalCard();
      prev(t);
      var hint = $("rr-journal-fill-hint");
      if (hint) hint.style.display = "";
    };
    global.fillJournalFromTrade.__rrPatched = true;
  }

  function patchDeleteTradeRecord() {
    var prev = global.deleteTradeRecord;
    if (typeof prev !== "function") return;
    if (prev.__rrPatched) return;
    global.deleteTradeRecord = function (id) {
      if (!confirm("确定删除这条交易记录?")) return;
      fetch("/delete_trade_record/" + id, { method: "POST", credentials: "same-origin" })
        .then(function (r) {
          return r.json();
        })
        .then(function (data) {
          if (data && data.ok) {
            loadTradeRecords({ soft: true });
            return;
          }
          if (typeof prev === "function") {
            /* fallthrough reload */
          }
          global.location.href =
            (global.location.pathname || "/records") + "?_ts=" + Date.now();
        })
        .catch(function () {
          global.location.href =
            (global.location.pathname || "/records") + "?_ts=" + Date.now();
        });
    };
    global.deleteTradeRecord.__rrPatched = true;
  }

  function bindPagers() {
    var tp = $("rr-trades-prev");
    var tn = $("rr-trades-next");
    var jp = $("rr-journals-prev");
    var jn = $("rr-journals-next");
    var rp = $("rr-reviews-prev");
    var rn = $("rr-reviews-next");
    var hideBtn = $("rr-journal-hide-btn");
    if (tp) {
      tp.addEventListener("click", function (ev) {
        ev.preventDefault();
        if (tradesPage <= 0) return;
        tradesPage -= 1;
        updatePager("trades");
        loadTradeRecords({ soft: true });
      });
    }
    if (tn) {
      tn.addEventListener("click", function (ev) {
        ev.preventDefault();
        if (tradesPage + 1 >= tradesPages) return;
        tradesPage += 1;
        updatePager("trades");
        loadTradeRecords({ soft: true });
      });
    }
    if (jp) {
      jp.addEventListener("click", function (ev) {
        ev.preventDefault();
        if (journalsPage <= 0) return;
        journalsPage -= 1;
        renderJournalsPage(true);
      });
    }
    if (jn) {
      jn.addEventListener("click", function (ev) {
        ev.preventDefault();
        if (journalsPage + 1 >= journalsPages) return;
        journalsPage += 1;
        renderJournalsPage(true);
      });
    }
    if (rp) {
      rp.addEventListener("click", function (ev) {
        ev.preventDefault();
        if (reviewsPage <= 0) return;
        reviewsPage -= 1;
        renderReviewsPage(true);
      });
    }
    if (rn) {
      rn.addEventListener("click", function (ev) {
        ev.preventDefault();
        if (reviewsPage + 1 >= reviewsPages) return;
        reviewsPage += 1;
        renderReviewsPage(true);
      });
    }
    if (hideBtn) {
      hideBtn.addEventListener("click", function (ev) {
        ev.preventDefault();
        hideJournalCard();
      });
    }
  }

  function init(opts) {
    opts = opts || {};
    if (!$("records-panel-root")) return;
    if (booted) {
      if (opts.refresh) {
        loadTradeRecords({ soft: true });
        loadJournalsPaged();
        loadReviewsPaged();
      }
      patchFillJournalFromTrade();
      patchDeleteTradeRecord();
      return;
    }
    booted = true;
    if (!global.journalCache) global.journalCache = {};
    if (!global.reviewCache) global.reviewCache = {};
    global.loadJournals = loadJournalsPaged;
    global.loadReviews = loadReviewsPaged;
    global.loadTradeRecords = loadTradeRecords;
    patchFillJournalFromTrade();
    patchDeleteTradeRecord();
    bindPagers();
    updatePager("trades");
    updatePager("journals");
    updatePager("reviews");
    loadTradeRecords({ soft: false });
    loadJournalsPaged();
    loadReviewsPaged();
  }

  global.RecordsReviewPage = {
    init: init,
    loadTradeRecords: loadTradeRecords,
    loadJournals: loadJournalsPaged,
    loadReviews: loadReviewsPaged,
    showJournalCard: showJournalCard,
    hideJournalCard: hideJournalCard,
  };

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", init);
  } else {
    init();
  }
})(typeof window !== "undefined" ? window : globalThis);
