<script setup lang="ts">
import { computed, ref } from "vue";

import { marketApi, type MarketWorkspaceData, type RotationMembersData } from "../../../shared/api/market";
import DataTable from "../../../shared/components/DataTable.vue";
import EmptyState from "../../../shared/components/EmptyState.vue";

const props = defineProps<{ data: MarketWorkspaceData }>();
const order = ref<"oldest" | "latest">("oldest");
const selectedSector = ref("");
const selectedDate = ref("");
const members = ref<RotationMembersData | null>(null);
const memberLoading = ref(false);
const memberError = ref("");
const history = computed(() => order.value === "oldest" ? props.data.history ?? [] : [...(props.data.history ?? [])].reverse());
const appearances = computed(() => (props.data.history ?? []).map((day) => ({
  trade_date: day.trade_date,
  sector: ((day.sectors as Record<string, unknown>[] | undefined) ?? []).find((item) => item.name === selectedSector.value),
})).filter((item) => item.sector));
const memberColumns = [
  { key: "code", label: "代码", code: true, sortable: true },
  { key: "name", label: "股票", sortable: true },
  { key: "change", label: "涨跌幅（%）", numeric: true, sortable: true, format: percent },
  { key: "open", label: "开盘（元）", numeric: true, sortable: true, format: decimal },
  { key: "close", label: "收盘（元）", numeric: true, sortable: true, format: decimal },
  { key: "amount", label: "成交额（亿）", numeric: true, sortable: true, format: amount },
  { key: "quoted", label: "行情状态", format: (value: unknown) => value ? "正常交易" : "当日无行情" },
];
const sortKey = ref("change");
const sortDirection = ref<"asc" | "desc">("desc");
const memberRows = computed(() => {
  const rows = members.value?.items ?? [];
  const direction = sortDirection.value === "asc" ? 1 : -1;
  return [...rows].sort((left, right) => {
    if (Boolean(left.quoted) !== Boolean(right.quoted)) return left.quoted ? -1 : 1;
    return compare(left[sortKey.value], right[sortKey.value]) * direction;
  });
});

async function selectSector(sector: Record<string, unknown>, tradeDate: unknown): Promise<void> {
  const name = String(sector.name ?? "");
  const date = String(tradeDate ?? "");
  if (name === selectedSector.value && date === selectedDate.value) {
    selectedSector.value = ""; selectedDate.value = ""; members.value = null; memberError.value = "";
    return;
  }
  selectedSector.value = name;
  selectedDate.value = date;
  memberLoading.value = true;
  memberError.value = "";
  try {
    members.value = await marketApi.rotationMembers(name, date);
  } catch (error) {
    members.value = null;
    memberError.value = error instanceof Error ? error.message : "板块成分股读取失败";
  } finally {
    memberLoading.value = false;
  }
}

function sort(key: string): void {
  if (sortKey.value === key) sortDirection.value = sortDirection.value === "asc" ? "desc" : "asc";
  else { sortKey.value = key; sortDirection.value = "desc"; }
}

function exportCsv(): void {
  const lines = [["日期", "排名", "板块", "涨停家数", "强度", "领涨股"]];
  for (const day of props.data.history ?? []) {
    for (const sector of (day.sectors as Record<string, unknown>[] | undefined) ?? []) {
      lines.push([String(day.trade_date ?? ""), String(sector.rank ?? ""), String(sector.name ?? ""), String(sector.count ?? ""), String(sector.strength ?? ""), String(sector.leader ?? "")]);
    }
  }
  const content = lines.map((line) => line.map((value) => `"${value.replaceAll('"', '""')}"`).join(",")).join("\r\n");
  const link = document.createElement("a");
  link.href = URL.createObjectURL(new Blob(["\ufeff", content], { type: "text/csv;charset=utf-8" }));
  link.download = `板块轮动-${props.data.trade_date}.csv`;
  link.click(); URL.revokeObjectURL(link.href);
}

function compare(left: unknown, right: unknown): number {
  const a = Number(left); const b = Number(right);
  if (Number.isFinite(a) && Number.isFinite(b)) return a - b;
  return String(left ?? "").localeCompare(String(right ?? ""), "zh-CN");
}
function numeric(value: unknown, digits: number): string {
  if (value === null || value === undefined || value === "") return "";
  const number = Number(value);
  return Number.isFinite(number) ? number.toFixed(digits) : "";
}
function percent(value: unknown): string { return numeric(value, 2); }
function decimal(value: unknown): string { return numeric(value, 2); }
function amount(value: unknown): string {
  if (value === null || value === undefined || value === "") return "";
  const number = Number(value);
  return Number.isFinite(number) ? (number / 100_000_000).toFixed(2) : "";
}
</script>

<template>
  <header class="page-header market-page-header">
    <div><h1>板块轮动</h1><p class="page-subtitle">最近9个交易日每日Top12热点 · 数据截至 {{ data.trade_date }}</p></div>
    <div class="page-actions"><div class="seg-control"><button type="button" :class="{ active: order === 'oldest' }" @click="order = 'oldest'">由远到近</button><button type="button" :class="{ active: order === 'latest' }" @click="order = 'latest'">由近到远</button></div><button class="btn btn-small" type="button" @click="exportCsv">导出 CSV</button></div>
  </header>
  <section class="card rotation-trajectory">
    <header class="card-header"><h2>热点轨迹</h2><span class="faint">{{ selectedSector ? `已联动高亮 ${selectedSector}` : "点击任意板块追踪其连续性" }}</span><span class="tag rotation-top-tag">每日Top12热点</span></header>
    <div class="rotation-legend"><span><i class="heat-high"></i>强度高（90+）</span><span><i class="heat-medium"></i>强度中（70–89）</span><span><i class="heat-low"></i>强度低（70以下）</span></div>
    <div v-if="selectedSector" class="rotation-tracker"><strong>{{ selectedSector }}</strong><span>近9日在榜 {{ appearances.length }}天 · 最高排名 {{ appearances.length ? Math.min(...appearances.map((item) => Number(item.sector?.rank ?? 99))) : "--" }}</span><button class="btn btn-small" type="button" @click="selectedSector = ''; selectedDate = ''; members = null">取消追踪</button></div>
    <div class="rotation-days">
      <article v-for="day in history" :key="String(day.trade_date)" class="rotation-day">
        <header><time>{{ String(day.trade_date).slice(5) }}</time><span>{{ ((day.sectors as unknown[]) ?? []).length }}个热点</span></header>
        <div>
          <button v-for="sector in (day.sectors as Record<string, unknown>[]) ?? []" :key="String(sector.name)" type="button" class="rotation-sector" :class="[{ selected: selectedSector === sector.name }, Number(sector.strength) >= 90 ? 'heat-high' : Number(sector.strength) >= 70 ? 'heat-medium' : 'heat-low']" @click="selectSector(sector, day.trade_date)">
            <span>{{ sector.rank }}</span><strong>{{ sector.name }}</strong><small>{{ sector.count }}家 · {{ Number(sector.strength).toFixed(0) }}</small>
          </button>
        </div>
      </article>
    </div>
  </section>
  <section class="card rotation-members">
    <header class="card-header"><h2>{{ members?.sector_name ? `${members.sector_name}成分股` : "板块成分股" }}</h2><span class="faint">{{ members ? `${members.trade_date} · ${members.quoted_count}/${members.member_count}只` : selectedSector || "点击上方任意板块查看成分股" }}</span></header>
    <div v-if="memberLoading" class="workspace-state">正在核验板块成分行情</div>
    <EmptyState v-else-if="memberError" title="成分行情暂不可用" :description="memberError" />
    <DataTable v-else-if="memberRows.length" :columns="memberColumns" :rows="memberRows" :sort-key="sortKey" :sort-direction="sortDirection" @sort="sort" />
    <EmptyState v-else title="尚未选择板块" description="点击热点轨迹中的板块后显示目标日期的申万成分股。" />
  </section>
</template>
