<script setup lang="ts">
import { h, ref, computed, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import {
  NSpin, NCard, NSelect, NEmpty, NDataTable, NTag, NSwitch, NButton, useMessage,
} from 'naive-ui';
import dayjs from 'dayjs';
import { fetchDashboard, type DashboardResult } from '@/api/roi';
import ConfidenceBadge from '@/components/roi/ConfidenceBadge.vue';
import CategoryStackedBar from '@/components/roi/CategoryStackedBar.vue';
import RevenuePieChart from '@/components/roi/RevenuePieChart.vue';

const router = useRouter();
const message = useMessage();
const loading = ref(true);

type WindowKey = 'lifetime' | 'ytd' | 'mtd' | 'custom';
const windowKey = ref<WindowKey>('lifetime');

function rangeOf(key: WindowKey): { from: string; to: string } {
  const today = dayjs().format('YYYY-MM-DD');
  if (key === 'lifetime') return { from: '2020-01-01', to: today };
  if (key === 'ytd') return { from: dayjs().startOf('year').format('YYYY-MM-DD'), to: today };
  return { from: dayjs().startOf('month').format('YYYY-MM-DD'), to: today };
}

const lifetimeData = ref<DashboardResult | null>(null);
const ytdData = ref<DashboardResult | null>(null);
const mtdData = ref<DashboardResult | null>(null);

async function loadAll() {
  loading.value = true;
  try {
    const [l, y, m] = await Promise.all([
      fetchDashboard(rangeOf('lifetime').from, rangeOf('lifetime').to),
      fetchDashboard(rangeOf('ytd').from, rangeOf('ytd').to),
      fetchDashboard(rangeOf('mtd').from, rangeOf('mtd').to),
    ]);
    lifetimeData.value = l.data.data;
    ytdData.value = y.data.data;
    mtdData.value = m.data.data;
  } catch (e: any) {
    message.error('加载失败:' + (e?.response?.data?.message || e.message));
  } finally {
    loading.value = false;
  }
}

onMounted(loadAll);

const activeData = computed(() => {
  if (windowKey.value === 'lifetime') return lifetimeData.value;
  if (windowKey.value === 'ytd') return ytdData.value;
  return mtdData.value;
});

function fmtCurrency(n: number | null | undefined): string {
  if (n === null || n === undefined) return '—';
  return `¥${Math.round(n).toLocaleString()}`;
}
function fmtPercent(n: number | null | undefined): string {
  if (n === null || n === undefined) return '—';
  return `${n.toFixed(1)}%`;
}
function roiColor(n: number | null | undefined): string {
  if (n === null || n === undefined) return 'var(--color-text-muted)';
  if (n >= 100) return '#0D9668';
  if (n >= 0) return '#D4920A';
  return '#DC2626';
}

const CATEGORY_META: Record<string, { emoji: string; label: string; color: 'success' | 'info' | 'warning' | 'error' | 'default' }> = {
  cash_cow:        { emoji: '💰', label: '现金牛',     color: 'success' },
  efficiency_tool: { emoji: '⚙️', label: '效能工具',   color: 'info' },
  moat:            { emoji: '💎', label: '资本护城河', color: 'warning' },
  composite:       { emoji: '🚀', label: '复合型',     color: 'error' },
  uncategorized:   { emoji: '◯',  label: '未打标',     color: 'default' },
};

// 筛选状态
const selectedCategories = ref<string[]>([]);  // 空数组 = 全部
const hideZeroCost = ref(true);

function toggleCategory(cat: string) {
  const i = selectedCategories.value.indexOf(cat);
  if (i >= 0) selectedCategories.value.splice(i, 1);
  else selectedCategories.value.push(cat);
}

function chipColor(t: string): string {
  return ({ success: '#0D9668', info: '#3B5998', warning: '#D4920A', error: '#DC2626', default: '#666' } as Record<string, string>)[t] || '#666';
}

// 按分类计数(基于当前活动窗口)
const categoryStats = computed(() => {
  const stats: Record<string, { count: number; totalCost: number; totalRevenue: number }> = {};
  for (const k of Object.keys(CATEGORY_META)) {
    stats[k] = { count: 0, totalCost: 0, totalRevenue: 0 };
  }
  const items = activeData.value?.projects || [];
  for (const p of items) {
    const k = p.category || 'uncategorized';
    if (!stats[k]) stats[k] = { count: 0, totalCost: 0, totalRevenue: 0 };
    stats[k].count += 1;
    stats[k].totalCost += p.totalCost;
    stats[k].totalRevenue += p.totalRevenue;
  }
  return stats;
});

// 经过筛选/排序的项目列表
const filteredProjects = computed(() => {
  let items = (activeData.value?.projects || []).slice();
  if (selectedCategories.value.length > 0) {
    items = items.filter(p => selectedCategories.value.includes(p.category || 'uncategorized'));
  }
  if (hideZeroCost.value) {
    items = items.filter(p => p.totalCost > 0);
  }
  return items;
});

const projectColumns = [
  {
    title: '项目', key: 'name',
    render: (row: any) => row.name,
    sorter: (a: any, b: any) => (a.name || '').localeCompare(b.name || ''),
  },
  {
    title: '定位', key: 'category',
    render: (row: any) => {
      const meta = CATEGORY_META[row.category || 'uncategorized'];
      return h(NTag, { type: meta.color, size: 'small', round: true }, () => `${meta.emoji} ${meta.label}`);
    },
    filterOptions: Object.entries(CATEGORY_META).map(([k, v]) => ({ label: `${v.emoji} ${v.label}`, value: k })),
    filter: (value: any, row: any) => (row.category || 'uncategorized') === value,
  },
  { title: '成本', key: 'totalCost', render: (row: any) => fmtCurrency(row.totalCost),
    sorter: (a: any, b: any) => a.totalCost - b.totalCost },
  { title: '产出', key: 'totalRevenue', render: (row: any) => fmtCurrency(row.totalRevenue),
    sorter: (a: any, b: any) => a.totalRevenue - b.totalRevenue },
  {
    title: 'ROI', key: 'roiValue',
    render: (row: any) => h('span', { style: { color: roiColor(row.roiValue), fontWeight: 600 } }, fmtPercent(row.roiValue)),
    sorter: (a: any, b: any) => (a.roiValue ?? -Infinity) - (b.roiValue ?? -Infinity),
    sortOrder: 'descend' as const,  // 默认按 ROI 降序
    defaultSortOrder: 'descend' as const,
  },
  { title: '置信度', key: 'confidence', render: (row: any) => h(ConfidenceBadge as any, { confidence: row.confidence, showLabel: false }) },
  {
    title: '操作', key: 'actions', render: (row: any) => h('a', {
      style: { color: 'var(--color-primary-hex)', cursor: 'pointer' },
      onClick: () => router.push(`/projects/${row.projectId}/roi`),
    }, '查看 →'),
  },
];

</script>

<template>
  <div class="dashboard-page">
    <NSpin :show="loading">
      <!-- 3 张 ROI 大卡片 -->
      <div class="kpi-grid">
        <article class="kpi-card kpi-hero">
          <div class="kpi-label">公司累计 ROI</div>
          <div class="kpi-value-row">
            <span class="kpi-value tabular-nums" :style="{ color: roiColor(lifetimeData?.summary.roiValue) }">
              {{ fmtPercent(lifetimeData?.summary.roiValue) }}
            </span>
          </div>
          <div class="kpi-meta" v-if="lifetimeData">
            <span class="kpi-meta-row"><span class="kpi-meta-label">成本</span><span class="tabular-nums">{{ fmtCurrency(lifetimeData.summary.totalCost) }}</span></span>
            <span class="kpi-meta-row"><span class="kpi-meta-label">产出</span><span class="tabular-nums">{{ fmtCurrency(lifetimeData.summary.totalRevenue) }}</span></span>
          </div>
        </article>
        <article class="kpi-card">
          <div class="kpi-label">本月 ROI<span class="kpi-suffix">MTD</span></div>
          <div class="kpi-value-row">
            <span class="kpi-value tabular-nums" :style="{ color: roiColor(mtdData?.summary.roiValue) }">
              {{ fmtPercent(mtdData?.summary.roiValue) }}
            </span>
          </div>
          <div class="kpi-meta" v-if="mtdData">
            <span class="kpi-meta-row"><span class="kpi-meta-label">成本</span><span class="tabular-nums">{{ fmtCurrency(mtdData.summary.totalCost) }}</span></span>
            <span class="kpi-meta-row"><span class="kpi-meta-label">产出</span><span class="tabular-nums">{{ fmtCurrency(mtdData.summary.totalRevenue) }}</span></span>
          </div>
        </article>
        <article class="kpi-card">
          <div class="kpi-label">本年 ROI<span class="kpi-suffix">YTD</span></div>
          <div class="kpi-value-row">
            <span class="kpi-value tabular-nums" :style="{ color: roiColor(ytdData?.summary.roiValue) }">
              {{ fmtPercent(ytdData?.summary.roiValue) }}
            </span>
          </div>
          <div class="kpi-meta" v-if="ytdData">
            <span class="kpi-meta-row"><span class="kpi-meta-label">成本</span><span class="tabular-nums">{{ fmtCurrency(ytdData.summary.totalCost) }}</span></span>
            <span class="kpi-meta-row"><span class="kpi-meta-label">产出</span><span class="tabular-nums">{{ fmtCurrency(ytdData.summary.totalRevenue) }}</span></span>
          </div>
        </article>
      </div>

      <!-- 切换时间窗口 -->
      <div class="section-divider">
        <div>
          <div class="eyebrow">Business lines</div>
          <h2 class="section-title">业务线分布</h2>
        </div>
        <NSelect v-model:value="windowKey" :options="[
          { label: '累计 (LTD)', value: 'lifetime' },
          { label: '本年 (YTD)', value: 'ytd' },
          { label: '本月 (MTD)', value: 'mtd' },
        ]" style="width:160px" size="small" />
      </div>

      <!-- 堆叠图 + 饼图 -->
      <div class="charts-row">
        <NCard size="small" title="各核心业务线 ROI 堆叠图">
          <CategoryStackedBar v-if="activeData" :by-category="activeData.byCategory" />
          <NEmpty v-else />
        </NCard>
        <NCard size="small" title="各业务线产出占比">
          <RevenuePieChart v-if="activeData" :by-category="activeData.byCategory" />
          <NEmpty v-else />
        </NCard>
      </div>

      <!-- 项目明细表 -->
      <NCard size="small" style="margin-top:16px">
        <template #header>
          <div class="table-header">
            <div style="display:flex;align-items:center;gap:8px">
              <span style="font-weight:600">项目明细</span>
              <span class="result-count">显示 {{ filteredProjects.length }} / {{ activeData?.projects.length || 0 }} 项</span>
            </div>
            <div class="category-chips">
              <button
                v-for="(meta, k) in CATEGORY_META"
                :key="k"
                class="chip"
                :class="{ active: selectedCategories.includes(k), disabled: (categoryStats[k]?.count || 0) === 0 }"
                :style="selectedCategories.includes(k) ? { background: chipColor(meta.color), color: '#fff', borderColor: chipColor(meta.color) } : {}"
                :disabled="(categoryStats[k]?.count || 0) === 0"
                @click="toggleCategory(k)"
              >
                {{ meta.emoji }} {{ meta.label }}
                <span class="chip-count">{{ categoryStats[k]?.count || 0 }}</span>
              </button>
              <NButton v-if="selectedCategories.length > 0" size="tiny" text type="primary" @click="selectedCategories = []">清空</NButton>
              <span class="filter-divider">|</span>
              <span class="filter-label">仅看有成本数据</span>
              <NSwitch v-model:value="hideZeroCost" size="small" />
            </div>
          </div>
        </template>
        <NDataTable
          v-if="activeData"
          :columns="projectColumns"
          :data="filteredProjects"
          :max-height="500"
          :row-key="(row: any) => row.projectId"
          striped
        />
        <NEmpty v-else />
      </NCard>
    </NSpin>
  </div>
</template>

<style scoped>
.dashboard-page {
  padding: var(--space-2) 0 clamp(var(--space-8), 4vw, var(--space-16));
  width: 100%;
}

/* ─────── Editorial 页头 ─────── */
.page-header {
  margin-bottom: var(--space-10);
  padding-bottom: var(--space-6);
  border-bottom: 1px solid var(--color-border-subtle);
}
.eyebrow {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-muted);
  margin-bottom: var(--space-3);
}
.page-title {
  font-family: var(--font-sans);
  font-size: var(--text-display);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text-primary);
  font-variant-numeric: tabular-nums;
  margin: 0;
}
.page-lede {
  margin-top: var(--space-3);
  font-size: var(--text-md);
  color: var(--color-text-secondary);
  line-height: 1.5;
  max-width: 56ch;
}

/* ─────── KPI 卡片 (Editorial Data Console) ─────── */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: clamp(var(--space-3), 1vw, var(--space-5));
}
.kpi-card.kpi-hero {
  grid-column: span 1;
}
@media (min-width: 1400px) {
  .kpi-grid { grid-template-columns: 1.4fr 1fr 1fr; }
}
.kpi-card {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-xl);
  padding: var(--space-6) var(--space-7);
  transition: border-color var(--duration-base) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out),
              transform var(--duration-base) var(--ease-out);
  position: relative;
  overflow: hidden;
}
.kpi-card::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, var(--color-bg-card) 0%, var(--color-bg-subtle) 100%);
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-out);
  pointer-events: none;
}
.kpi-card:hover {
  border-color: var(--color-border);
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}
.kpi-card.kpi-hero {
  border-left: 3px solid var(--color-primary);
}
.kpi-label {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-text-muted);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.kpi-suffix {
  font-size: 10px;
  color: var(--color-text-muted);
  padding: 1px 6px;
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-xs);
  letter-spacing: 0.05em;
}
.kpi-value-row {
  margin-top: var(--space-3);
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
}
.kpi-value {
  font-family: var(--font-mono);
  font-size: var(--text-3xl);
  font-weight: var(--weight-semibold);
  letter-spacing: -0.025em;
  line-height: 1;
}
.kpi-meta {
  margin-top: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding-top: var(--space-3);
  border-top: 1px dashed var(--color-border-subtle);
}
.kpi-meta-row {
  display: flex;
  justify-content: space-between;
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.kpi-meta-label {
  color: var(--color-text-muted);
}

/* ─────── Section 分隔 ─────── */
.section-divider {
  margin-top: var(--space-12);
  margin-bottom: var(--space-5);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
}
.section-title {
  font-family: var(--font-sans);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text-primary);
  margin: var(--space-2) 0 0 0;
}

.charts-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
  gap: clamp(var(--space-3), 1vw, var(--space-5));
}

/* ─────── 项目明细表 ─────── */
.table-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.category-chips {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.chip {
  border: 1px solid var(--color-border);
  background: var(--color-bg-card);
  border-radius: var(--radius-full);
  padding: 4px 12px;
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  cursor: pointer;
  user-select: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--color-text-secondary);
  transition: all var(--duration-fast) var(--ease-out);
}
.chip:hover:not(.disabled) {
  border-color: var(--color-border-strong);
  color: var(--color-text-primary);
  background: var(--color-bg-subtle);
}
.chip.active { font-weight: var(--weight-semibold); box-shadow: var(--shadow-sm); }
.chip.disabled { opacity: 0.35; cursor: not-allowed; }
.chip-count {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--color-text-muted);
  opacity: 1;
  margin-left: 6px;
  padding-left: 8px;
  border-left: 1px solid currentColor;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.chip.active .chip-count {
  color: oklch(1 0 0 / 0.7);
}
.result-count {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}
.filter-divider { color: var(--color-border); margin: 0 var(--space-1); user-select: none; }
.filter-label { font-size: var(--text-sm); color: var(--color-text-muted); }

/* 自适应:auto-fit + minmax 已经在窄屏自动单列, 这里仅微调 padding */
@media (max-width: 768px) {
  .page-header { padding-bottom: var(--space-4); margin-bottom: var(--space-6); }
  .section-divider { margin-top: var(--space-8); flex-wrap: wrap; }
}
</style>
