<script setup lang="ts">
import { computed, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";

import { marketApi, type EntityDetail, type EntityMetric, type MarketEntity, type ThemeDetailData } from "../../shared/api/market";
import { reviewApi } from "../../shared/api/review";
import DataTable from "../../shared/components/DataTable.vue";
import EmptyState from "../../shared/components/EmptyState.vue";
import MarketPreviewPanel from "../../shared/market/MarketPreviewPanel.vue";
import { useMarketStore } from "../../shared/stores/market";
import { useUiStore } from "../../shared/stores/ui";
import StockNotes from "../../pages/review/StockNotes.vue";

const route = useRoute();
const router = useRouter();
const market = useMarketStore();
const ui = useUiStore();
const detail = ref<EntityDetail | null>(null);
const theme = ref<ThemeDetailData | null>(null);
const loading = ref(true);
const error = ref("");
const watchlisted = ref(false);
const watchBusy = ref(false);
const sortKey = ref("change");
const sortDirection = ref<"asc" | "desc">("desc");

const entity = computed<MarketEntity>(() => ({
  entity_type: String(route.params.entityType) as MarketEntity["entity_type"],
  identifier: String(route.params.identifier),
  code: String(route.query.code ?? String(route.params.identifier).split(".")[0]),
  name: String(route.query.name ?? route.params.identifier),
  sector: route.query.sector ? String(route.query.sector) : null,
}));
const resolvedEntity = computed(() => detail.value?.entity ?? entity.value);
const themeRows = computed(() => {
  const rows = theme.value?.members ?? [];
  const direction = sortDirection.value === "asc" ? 1 : -1;
  return [...rows].sort((left, right) => compare(left[sortKey.value], right[sortKey.value]) * direction);
});
const themeColumns = [
  { key: "code", label: "代码", code: true, sortable: true },
  { key: "name", label: "股票", sortable: true },
  { key: "change", label: "涨跌幅（%）", numeric: true, sortable: true, format: decimal },
  { key: "close", label: "收盘（元）", numeric: true, sortable: true, format: decimal },
  { key: "amount", label: "成交额（亿）", numeric: true, sortable: true, format: amountCell },
  { key: "quoted", label: "行情状态", format: (value: unknown) => value ? "正常交易" : "当日无行情" },
];

async function load(): Promise<void> {
  loading.value = true;
  error.value = "";
  detail.value = null;
  theme.value = null;
  try {
    const [marketDetail, review, themeDetail] = await Promise.all([
      marketApi.detail(entity.value, market.selectedDate),
      entity.value.entity_type === "stock" ? reviewApi.workspace(market.selectedDate) : null,
      entity.value.entity_type === "theme" ? marketApi.themeDetail(entity.value.identifier, market.selectedDate) : null,
    ]);
    detail.value = marketDetail;
    theme.value = themeDetail;
    watchlisted.value = Boolean(review?.watchlist.some((item) => item.identifier === entity.value.identifier));
  } catch (reason) {
    error.value = reason instanceof Error ? reason.message : "行情详情读取失败";
  } finally {
    loading.value = false;
  }
}

async function toggleWatch(): Promise<void> {
  if (watchBusy.value) return;
  watchBusy.value = true;
  try {
    if (watchlisted.value) await reviewApi.removeWatch(resolvedEntity.value.identifier);
    else await reviewApi.addWatch(resolvedEntity.value.identifier);
    watchlisted.value = !watchlisted.value;
    ui.showToast(watchlisted.value ? "已加入自选" : "已移出自选");
  } catch (reason) {
    ui.showToast(reason instanceof Error ? reason.message : "自选操作失败");
  } finally {
    watchBusy.value = false;
  }
}

function openTrend(): void {
  void router.push({ path: "/workspace/heaven", query: { mode: "trend", query: resolvedEntity.value.code } });
}

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

function formatMetric(metric: EntityMetric): string {
  if (metric.value === null || metric.value === undefined) return "";
  if (metric.key === "amount") return amount(metric.value);
  if (metric.key === "volume") return `${(metric.value / 10_000).toFixed(2)} 万`;
  return `${metric.value.toFixed(2)} ${metric.unit}`.trim();
}
function money(value: number | null | undefined): string {
  return value === null || value === undefined ? "" : `${(value * 100).toFixed(2)} 万`;
}
function decimal(value: unknown): string {
  const parsed = Number(value); return Number.isFinite(parsed) ? parsed.toFixed(2) : "";
}
function amount(value: unknown): string {
  const parsed = Number(value); return Number.isFinite(parsed) ? `${(parsed / 100_000_000).toFixed(2)} 亿` : "";
}
function amountCell(value: unknown): string {
  const parsed = Number(value); return Number.isFinite(parsed) ? (parsed / 100_000_000).toFixed(2) : "";
}
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");
}

watch([() => route.params.identifier, () => market.selectedDate], load, { immediate: true });
</script>

<template>
  <main class="page-frame entity-detail-page">
    <div v-if="loading" class="card workspace-state">正在读取完整行情详情</div>
    <EmptyState v-else-if="error" class="card" title="行情详情暂不可用" :description="error" />
    <template v-else-if="detail">
      <header class="page-header entity-detail-heading">
        <div>
          <span class="entity-detail-code">{{ detail.entity.code }}</span>
          <h1>{{ detail.entity.name }}</h1>
          <span v-if="detail.entity.sector" class="tag">{{ detail.entity.sector }}</span>
        </div>
        <div class="entity-detail-price">
          <strong class="numeric">{{ detail.price.toFixed(2) }}</strong>
          <span v-if="detail.change !== null" class="numeric" :class="detail.change >= 0 ? 'up' : 'down'">{{ detail.change >= 0 ? '+' : '' }}{{ detail.change.toFixed(2) }}%</span>
          <small>数据日期 {{ detail.trade_date }}</small>
        </div>
        <div v-if="detail.entity.entity_type === 'stock'" class="page-actions entity-detail-actions">
          <button class="btn" type="button" :disabled="watchBusy" @click="toggleWatch">{{ watchlisted ? "移出自选" : "加入自选" }}</button>
          <button class="btn btn-primary" type="button" @click="openTrend">进入观势</button>
        </div>
      </header>

      <section class="entity-detail-grid">
        <MarketPreviewPanel :entity="resolvedEntity" class="card entity-chart" />
        <article class="card entity-metrics-card">
          <header class="card-header"><h2>交易数据</h2><span class="faint">对应 {{ detail.trade_date }}</span></header>
          <dl class="entity-metrics">
            <div v-for="metric in detail.metrics" :key="metric.key"><dt>{{ metric.label }}</dt><dd class="numeric">{{ formatMetric(metric) }}</dd></div>
          </dl>
        </article>
      </section>

      <div v-if="detail.entity.entity_type === 'stock'" class="entity-stock-grid">
        <article class="card entity-flow-card">
          <header class="card-header"><h2>资金流</h2><span class="faint">同一正式数据口径</span></header>
          <dl v-if="detail.money_flow?.available" class="entity-metrics entity-flow-metrics">
            <div><dt>当日净流入</dt><dd class="numeric">{{ money(detail.money_flow.net_million) }}</dd></div>
            <div><dt>大单净流入</dt><dd class="numeric">{{ money(detail.money_flow.large_million) }}</dd></div>
            <div><dt>近5日净流入</dt><dd class="numeric">{{ money(detail.money_flow.net_5d_million) }}</dd></div>
            <div><dt>近5日/流通市值</dt><dd class="numeric">{{ detail.money_flow.flow_to_circ_mv_5d === null ? "" : `${detail.money_flow.flow_to_circ_mv_5d.toFixed(4)}%` }}</dd></div>
          </dl>
          <EmptyState v-else title="资金流暂不可用" description="当前日期尚无达到覆盖标准的同口径资金流数据。" />
        </article>
        <article class="card entity-event-card">
          <header class="card-header"><h2>事件逻辑</h2><span v-if="detail.event" class="tag">{{ detail.event.status }}</span></header>
          <div v-if="detail.event" class="entity-event-body">
            <strong>{{ detail.event.reason || `${detail.event.status}原因待补充` }}</strong>
            <dl><div><dt>连板</dt><dd>{{ detail.event.streak ?? "" }}</dd></div><div><dt>首次</dt><dd>{{ detail.event.first_time ?? "" }}</dd></div><div><dt>最后</dt><dd>{{ detail.event.last_time ?? "" }}</dd></div><div><dt>开板</dt><dd>{{ detail.event.open_times ?? "" }}</dd></div></dl>
          </div>
          <EmptyState v-else title="当日无特殊事件" description="该股票当日不在涨停、炸板或跌停事件池中。" />
        </article>
      </div>

      <section v-if="detail.entity.entity_type === 'theme'" class="card entity-members-card">
        <header class="card-header"><h2>题材成分股</h2><span class="faint">{{ theme?.summary.quoted_count ?? 0 }} / {{ theme?.summary.member_count ?? 0 }}只有行情</span></header>
        <DataTable v-if="themeRows.length" :columns="themeColumns" :rows="themeRows" :sort-key="sortKey" :sort-direction="sortDirection" @sort="sort" />
        <EmptyState v-else title="暂无成分股" description="当前题材尚无可核验的成分股归档。" />
      </section>

      <StockNotes v-if="detail.entity.entity_type === 'stock'" :code="detail.entity.code" :name="detail.entity.name" />
    </template>
  </main>
</template>
