function exportStocks() {
  exportRows("涨停池", getVisibleStocks(), [
    ["股票代码", "code"], ["股票名称", "name"], ["连板", "streak"], ["涨幅%", "change"],
    ["价格", "price"], ["所属板块", "sector"], ["涨停原因", "reason"], ["首封", "first_time"],
    ["最后封板", "last_time"], ["开板次数", "open_times"], ["换手率%", "turnover_rate"],
    ["成交额亿", "amount_billion"], ["封单额万", "seal_amount_million"],
  ]);
}

function exportBroken() {
  exportRows("炸板池", getVisibleBrokenRows(), [
    ["股票代码", "code"], ["股票名称", "name"], ["现价涨幅%", "change"], ["距涨停%", "limitGap"],
    ["价格", "price"], ["所属板块", "sector"], ["首次触板", "first_time"], ["开板次数", "open_times"],
    ["换手率%", "turnover_rate"], ["成交额亿", "amount_billion"],
  ]);
}

function exportDown() {
  exportRows("跌停板", getVisibleDownRows(), [
    ["股票代码", "code"], ["股票名称", "name"], ["跌幅%", "change"], ["价格", "price"],
    ["所属板块", "sector"], ["换手率%", "turnover_rate"], ["成交额亿", "amount_billion"],
  ]);
}

function exportYesterday() {
  exportRows("昨日涨停", getVisibleYesterdayRows(), [
    ["股票代码", "code"], ["股票名称", "name"], ["昨日高度", "prior_streak"],
    ["今日涨幅%", "current_change"], ["今日结果", "outcome"], ["当前高度", "current_streak"],
    ["所属板块", "sector"],
  ]);
}

function exportLadder() {
  const rows = (state.dashboard?.ladders || []).flatMap((group) => (group.stocks || []).map((stock) => ({
    level: group.label || group.level,
    ...stock,
  })));
  exportRows("市场天梯", rows, [
    ["梯队", "level"], ["股票代码", "code"], ["股票名称", "name"], ["所属板块", "sector"],
    ["封板时间", "first_time"], ["开板次数", "open_times"], ["封单额万", "seal_amount_million"], ["成交额亿", "amount_billion"],
  ]);
}

function exportRotation() {
  const sectorMap = new Map((state.dashboard?.sectors || []).map((sector) => [sector.name, sector]));
  const rows = (state.dashboard?.sector_rotation || []).map((row) => ({
    ...row,
    average_change: sectorMap.get(row.name)?.change ?? 0,
  }));
  exportRows("板块轮动", rows, [
    ["排名", "rank"], ["板块", "name"], ["趋势", "trend"], ["今日涨停", "count"],
    ["昨日涨停", "previous_count"], ["变化", "delta"], ["强度", "strength"],
    ["最高板", "max_streak"], ["平均涨幅%", "average_change"],
    ["领涨股", "leader"], ["涨停股成交额亿", "amount_billion"],
  ]);
}

function exportSentimentHistory() {
  const rows = state.sentimentHistory?.rows || [];
  if (!rows.length) {
    showToast("暂无可导出的情绪周期数据");
    return;
  }
  const exportRowsData = rows.map((row) => ({
    ...row,
    breadth_score: row.components?.breadth?.score,
    limit_ecology_score: row.components?.limit_ecology?.score,
    profit_effect_score: row.components?.profit_effect?.score,
    ladder_structure_score: row.components?.ladder_structure?.score,
    liquidity_score: row.components?.liquidity?.score,
  }));
  exportRows("情绪周期", exportRowsData, [
    ["交易日", "trade_date"], ["情绪温度", "score"], ["周期阶段", "phase"], ["方向", "direction"],
    ["涨停", "limit_up_count"], ["首板", "first_board_count"], ["二板", "second_board_count"],
    ["三板以上", "three_plus_count"], ["连板高度", "max_height"], ["炸板", "broken_count"],
    ["跌停", "limit_down_count"], ["昨日涨停", "previous_limit_count"],
    ["昨日涨停红盘", "previous_positive_count"], ["昨日涨停红盘率%", "previous_positive_rate"],
    ["市场宽度", "breadth_score"], ["涨停生态", "limit_ecology_score"],
    ["赚钱效应", "profit_effect_score"], ["连板结构", "ladder_structure_score"],
    ["成交活跃度", "liquidity_score"],
  ]);
}

function exportDragonTiger() {
  const rows = (state.dragonTiger?.traders || []).flatMap((trader) => (
    (trader.operations || []).map((operation) => ({
      trader_name: trader.name,
      identity_type: dragonIdentityLabel(trader.identity_type),
      ...operation,
    }))
  ));
  exportRows("游资龙虎榜", rows, [
    ["游资或席位", "trader_name"], ["身份", "identity_type"], ["股票代码", "code"],
    ["股票名称", "name"], ["方向", "direction"], ["涨幅%", "change"],
    ["买入百万元", "buy_million"], ["卖出百万元", "sell_million"], ["净额百万元", "net_buy_million"],
    ["关联席位", "seat_name"], ["上榜原因", "reason"],
  ]);
}

function exportHotMoneyProfiles() {
  const rows = state.hotMoneyProfiles?.profiles || [];
  if (!rows.length) {
    showToast("暂无可导出的游资档案");
    return;
  }
  downloadCsv(
    `游资档案-${todayString()}.csv`,
    ["游资名称", "简介", "关联营业部", "席位数量"],
    rows.map((profile) => [
      profile.name,
      profile.description,
      (profile.organizations || []).join("；"),
      number(profile.organization_count),
    ]),
  );
}

function exportRows(label, rows, columns) {
  const headers = columns.map(([header]) => header);
  const data = rows.map((row) => columns.map(([, key]) => row[key] ?? ""));
  downloadCsv(`${label}-${state.dashboard.meta.trade_date}.csv`, headers, data);
}

function downloadCsv(filename, headers, rows) {
  const lines = [headers, ...rows].map((row) => row.map(csvCell).join(","));
  const blob = new Blob(["\ufeff", lines.join("\r\n")], { type: "text/csv;charset=utf-8" });
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement("a");
  anchor.href = url;
  anchor.download = filename;
  anchor.click();
  URL.revokeObjectURL(url);
  showToast(`已导出 ${rows.length} 条数据`);
}

function csvCell(value) {
  let text = String(value ?? "");
  if (/^[=+\-@]/.test(text)) text = `'${text}`;
  return `"${text.replaceAll('"', '""')}"`;
}
