<script lang="ts" setup>
/**
 * 部门财务报表详情抽屉（C 端风格）
 * 英雄头 + 指标卡 + 诊所卡片 + 药品内嵌面板 + ExcelJS 导出
 */
import { computed, ref, watch } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';

import {
  Button,
  Empty,
  Pagination,
  Spin,
  Tag,
  message,
} from 'ant-design-vue';

import {
  getDepartmentFinanceReportDetailApi,
  getDepartmentFinanceStoreDrugDetailApi,
} from '#/views/finance/department-finance/api';
import {
  MEDICINE_SCOPE_NOTE,
  STORE_METRIC_FIELDS,
} from '#/views/finance/department-finance/config/metrics';
import { buildAndDownloadDepartmentFinanceExcel } from '#/views/finance/department-finance/utils/exportDepartmentFinanceExcel';

const loading = ref(false);
const exportLoading = ref(false);
const reportId = ref(0);
const detail = ref<any>(null);
const drugLoading = ref(false);
const drugItems = ref<any[]>([]);
const drugStoreName = ref('');
const selectedStoreId = ref<number | null>(null);
const storePage = ref(1);
const storePageSize = 8;

const [Drawer, drawerApi] = useVbenDrawer({
  onOpenChange(isOpen) {
    if (isOpen) {
      loadDetail();
    } else {
      detail.value = null;
      drugItems.value = [];
      drugStoreName.value = '';
      selectedStoreId.value = null;
      storePage.value = 1;
    }
  },
});

/** 金额千分位展示 */
function formatMoney(value: unknown): string {
  const n = Number(value);
  if (!Number.isFinite(n)) return '—';
  return n.toLocaleString(undefined, {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  });
}

/** 英雄头下方指标（开票合计已在头区突出，不再重复） */
const metricItems = computed(() => {
  const s = detail.value?.summary;
  if (!s) return [];
  return STORE_METRIC_FIELDS.map((f) => ({
    label: f.label,
    tip: 'tip' in f ? f.tip : '',
    value: s[f.key],
  }));
});

const allStores = computed(() => detail.value?.stores ?? []);

const storeTotal = computed(() => allStores.value.length);

/** 诊所前端分页切片 */
const pagedStores = computed(() => {
  const start = (storePage.value - 1) * storePageSize;
  return allStores.value.slice(start, start + storePageSize);
});

watch(storeTotal, () => {
  const maxPage = Math.max(1, Math.ceil(storeTotal.value / storePageSize) || 1);
  if (storePage.value > maxPage) storePage.value = maxPage;
});

/** 加载报表详情 */
async function loadDetail() {
  const data = drawerApi.getData<{ id: number }>();
  if (!data?.id) return;
  reportId.value = data.id;
  loading.value = true;
  selectedStoreId.value = null;
  drugItems.value = [];
  drugStoreName.value = '';
  storePage.value = 1;
  try {
    detail.value = await getDepartmentFinanceReportDetailApi(data.id);
  } finally {
    loading.value = false;
  }
}

/**
 * 查看诊所药品供货明细（再次点击同一诊所则收起）
 */
async function showStoreDrugs(storeId: number, name: string) {
  if (selectedStoreId.value === storeId) {
    closeDrugPanel();
    return;
  }
  selectedStoreId.value = storeId;
  drugStoreName.value = name;
  drugLoading.value = true;
  try {
    const res = await getDepartmentFinanceStoreDrugDetailApi({
      store_id: storeId,
      report_id: reportId.value,
    });
    drugItems.value = res.items ?? [];
  } catch (e: any) {
    message.error(e?.message || '加载药品明细失败');
    drugItems.value = [];
  } finally {
    drugLoading.value = false;
  }
}

/** 收起药品明细面板 */
function closeDrugPanel() {
  selectedStoreId.value = null;
  drugStoreName.value = '';
  drugItems.value = [];
}

/** 诊所分页切换 */
function onStorePageChange(page: number) {
  storePage.value = page;
}

/** 导出当前报表（ExcelJS 美化） */
async function handleExport() {
  if (!reportId.value || exportLoading.value) return;
  exportLoading.value = true;
  const hide = message.loading('正在生成 Excel…', 0);
  try {
    await buildAndDownloadDepartmentFinanceExcel(reportId.value);
    message.success('导出成功');
  } catch (e: any) {
    message.error(e?.message || '导出失败');
  } finally {
    hide();
    exportLoading.value = false;
  }
}

defineExpose({
  open(id: number) {
    drawerApi.setData({ id });
    drawerApi.open();
  },
});
</script>

<template>
  <Drawer
    :title="detail ? `报表详情 - ${detail.report_no}` : '报表详情'"
    class="w-[80%]"
  >
    <Spin :spinning="loading">
      <template v-if="detail">
        <!-- 英雄头：编号 + 区间 + 开票合计 + 导出 -->
        <div class="df-detail-hero">
          <div class="df-detail-hero__left">
            <div class="df-detail-hero__title">{{ detail.report_no }}</div>
            <div class="df-detail-hero__meta">
              <span>统计区间</span>
              <span>{{ detail.period_start }} ~ {{ detail.period_end }}</span>
            </div>
            <div class="df-detail-hero__meta">
              <span>生成时间</span>
              <span>{{ detail.generated_at }}</span>
            </div>
          </div>
          <div class="df-detail-hero__right">
            <div class="df-detail-hero__amount-label">开票合计</div>
            <div class="df-detail-hero__amount-value">
              ¥{{ formatMoney(detail.summary?.invoice_total ?? detail.invoice_total) }}
            </div>
            <Button
              type="primary"
              class="mt-3"
              :loading="exportLoading"
              @click="handleExport"
            >
              导出 Excel
            </Button>
          </div>
        </div>

        <!-- 口径说明：西药侧含非中药，已取消颗粒栏目 -->
        <div class="df-detail-note">{{ MEDICINE_SCOPE_NOTE }}</div>

        <!-- 指标卡 -->
        <div v-if="metricItems.length" class="df-detail-metrics">
          <div
            v-for="item in metricItems"
            :key="item.label"
            class="df-detail-metric"
          >
            <div class="df-detail-metric__label">
              {{ item.label }}
              <span v-if="item.tip" class="df-detail-metric__tip">{{ item.tip }}</span>
            </div>
            <div class="df-detail-metric__value">
              ¥{{ formatMoney(item.value) }}
            </div>
          </div>
        </div>

        <!-- 诊所卡片列表 -->
        <div class="df-detail-section-title">诊所明细</div>
        <div v-if="pagedStores.length" class="df-detail-store-grid">
          <div
            v-for="store in pagedStores"
            :key="store.id ?? store.store_id"
            class="df-detail-store"
            :class="{
              'df-detail-store--active': selectedStoreId === store.store_id,
            }"
          >
            <div class="df-detail-store__main">
              <div class="df-detail-store__name">{{ store.store_name }}</div>
              <div class="df-detail-store__metrics">
                <div
                  v-for="field in STORE_METRIC_FIELDS"
                  :key="field.key"
                  class="df-detail-store__metric"
                >
                  <span>
                    {{ field.label }}
                    <template v-if="'tip' in field && field.tip">
                      （{{ field.tip }}）
                    </template>
                  </span>
                  <span>¥{{ formatMoney(store[field.key]) }}</span>
                </div>
              </div>
              <div class="df-detail-store__total">
                <span>开票合计</span>
                <span>¥{{ formatMoney(store.invoice_total) }}</span>
              </div>
            </div>
            <div class="df-detail-store__footer">
              <Button
                size="small"
                :type="selectedStoreId === store.store_id ? 'primary' : 'default'"
                @click="showStoreDrugs(store.store_id, store.store_name)"
              >
                {{
                  selectedStoreId === store.store_id
                    ? '收起药品明细'
                    : '查看药品明细'
                }}
              </Button>
            </div>
          </div>
        </div>
        <Empty v-else-if="!loading" description="暂无诊所明细" />
        <div
          v-if="storeTotal > storePageSize"
          class="mt-3 flex justify-end"
        >
          <Pagination
            :current="storePage"
            :page-size="storePageSize"
            :total="storeTotal"
            size="small"
            @change="onStorePageChange"
          />
        </div>

        <!-- 药品明细内嵌面板 -->
        <div v-if="drugStoreName" class="df-detail-drug-panel">
          <div class="df-detail-drug-panel__head">
            <div class="df-detail-drug-panel__title">
              {{ drugStoreName }} · 药品供货明细
            </div>
            <Button size="small" @click="closeDrugPanel">收起</Button>
          </div>
          <Spin :spinning="drugLoading">
            <div v-if="drugItems.length" class="df-detail-drug-list">
              <div
                v-for="drug in drugItems"
                :key="drug.drug_id ?? drug.drug_number"
                class="df-detail-drug-row"
              >
                <div class="df-detail-drug-row__main">
                  <div class="df-detail-drug-row__name">
                    {{ drug.drug_name }}
                  </div>
                  <div class="df-detail-drug-row__sub">
                    <Tag v-if="drug.type_txt" color="blue">
                      {{ drug.type_txt }}
                    </Tag>
                    <span v-if="drug.drug_number" class="text-slate-400">
                      {{ drug.drug_number }}
                    </span>
                    <span>数量 {{ drug.number ?? '—' }}</span>
                  </div>
                </div>
                <div class="df-detail-drug-row__money">
                  <div class="df-detail-drug-row__price">
                    单价 ¥{{ formatMoney(drug.market_price) }}
                  </div>
                  <div class="df-detail-drug-row__total">
                    ¥{{ formatMoney(drug.total_supply_price) }}
                  </div>
                </div>
              </div>
            </div>
            <Empty
              v-else-if="!drugLoading"
              description="该诊所暂无药品供货明细"
            />
          </Spin>
        </div>
      </template>
      <Empty v-else-if="!loading" description="暂无报表详情" />
    </Spin>
  </Drawer>
</template>

<style scoped>
.df-detail-hero {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  align-items: flex-end;
  justify-content: space-between;
  padding: 18px 20px;
  margin-bottom: 16px;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  box-shadow: 0 1px 2px rgb(15 23 42 / 4%);
}
.df-detail-note {
  margin-bottom: 12px;
  padding: 10px 14px;
  font-size: 13px;
  line-height: 1.5;
  color: #475569;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
}
.dark .df-detail-note {
  color: #cbd5e1;
  background: #0b1220;
  border-color: #1e293b;
}
.df-detail-metric__tip {
  display: block;
  margin-top: 2px;
  font-size: 11px;
  font-weight: 400;
  color: #94a3b8;
}
.dark .df-detail-hero {
  background: #0f172a;
  border-color: #334155;
}
.df-detail-hero__title {
  margin-bottom: 10px;
  font-size: 20px;
  font-weight: 700;
  color: #1f4e79;
  letter-spacing: 0.02em;
}
.dark .df-detail-hero__title {
  color: #93c5fd;
}
.df-detail-hero__meta {
  display: flex;
  gap: 10px;
  justify-content: space-between;
  min-width: 260px;
  margin-bottom: 4px;
  font-size: 13px;
  color: #64748b;
}
.df-detail-hero__meta > span:last-child {
  color: #334155;
  text-align: right;
}
.dark .df-detail-hero__meta > span:last-child {
  color: #cbd5e1;
}
.df-detail-hero__right {
  text-align: right;
}
.df-detail-hero__amount-label {
  font-size: 13px;
  color: #64748b;
}
.df-detail-hero__amount-value {
  margin-top: 4px;
  font-size: 28px;
  font-weight: 700;
  line-height: 1.2;
  color: #2563eb;
}
.dark .df-detail-hero__amount-value {
  color: #60a5fa;
}

.df-detail-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}
.df-detail-metric {
  padding: 14px 14px 12px;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  transition:
    box-shadow 0.2s ease,
    border-color 0.2s ease;
}
.dark .df-detail-metric {
  background: #0f172a;
  border-color: #334155;
}
.df-detail-metric:hover {
  border-color: #93c5fd;
  box-shadow: 0 4px 12px rgb(15 23 42 / 6%);
}
.df-detail-metric__label {
  margin-bottom: 6px;
  font-size: 12px;
  color: #64748b;
}
.df-detail-metric__value {
  font-size: 16px;
  font-weight: 700;
  color: #1e293b;
}
.dark .df-detail-metric__value {
  color: #e2e8f0;
}

.df-detail-section-title {
  margin-bottom: 12px;
  font-size: 15px;
  font-weight: 600;
  color: #334155;
}
.dark .df-detail-section-title {
  color: #cbd5e1;
}

.df-detail-store-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 14px;
}
.df-detail-store {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  box-shadow: 0 1px 2px rgb(15 23 42 / 4%);
  transition:
    box-shadow 0.2s ease,
    border-color 0.2s ease;
}
.dark .df-detail-store {
  background: #0f172a;
  border-color: #334155;
}
.df-detail-store:hover {
  border-color: #93c5fd;
  box-shadow: 0 6px 16px rgb(15 23 42 / 8%);
}
.df-detail-store--active {
  border-color: #3b82f6;
  box-shadow: 0 0 0 1px #3b82f6;
}
.df-detail-store__main {
  flex: 1;
  padding: 14px 14px 10px;
}
.df-detail-store__name {
  margin-bottom: 10px;
  font-size: 15px;
  font-weight: 600;
  color: #1f4e79;
}
.dark .df-detail-store__name {
  color: #93c5fd;
}
.df-detail-store__metrics {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 10px;
}
.df-detail-store__metric {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 12px;
  color: #64748b;
}
.df-detail-store__metric > span:last-child {
  font-size: 13px;
  font-weight: 600;
  color: #334155;
}
.dark .df-detail-store__metric > span:last-child {
  color: #cbd5e1;
}
.df-detail-store__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-top: 12px;
  padding-top: 10px;
  font-size: 13px;
  color: #64748b;
  border-top: 1px dashed #e2e8f0;
}
.dark .df-detail-store__total {
  border-top-color: #1e293b;
}
.df-detail-store__total > span:last-child {
  font-size: 18px;
  font-weight: 700;
  color: #2563eb;
}
.dark .df-detail-store__total > span:last-child {
  color: #60a5fa;
}
.df-detail-store__footer {
  display: flex;
  justify-content: flex-end;
  padding: 10px 14px 12px;
  background: #fafafa;
  border-top: 1px solid #f1f5f9;
}
.dark .df-detail-store__footer {
  background: #0b1220;
  border-top-color: #1e293b;
}

.df-detail-drug-panel {
  margin-top: 20px;
  overflow: hidden;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
}
.dark .df-detail-drug-panel {
  background: #0f172a;
  border-color: #334155;
}
.df-detail-drug-panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background: #f8fafc;
  border-bottom: 1px solid #f1f5f9;
}
.dark .df-detail-drug-panel__head {
  background: #0b1220;
  border-bottom-color: #1e293b;
}
.df-detail-drug-panel__title {
  font-size: 14px;
  font-weight: 600;
  color: #1f4e79;
}
.dark .df-detail-drug-panel__title {
  color: #93c5fd;
}
.df-detail-drug-list {
  display: flex;
  flex-direction: column;
  max-height: 420px;
  overflow: auto;
}
.df-detail-drug-row {
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid #f1f5f9;
}
.dark .df-detail-drug-row {
  border-bottom-color: #1e293b;
}
.df-detail-drug-row:last-child {
  border-bottom: none;
}
.df-detail-drug-row:nth-child(even) {
  background: #fafafa;
}
.dark .df-detail-drug-row:nth-child(even) {
  background: #0b1220;
}
.df-detail-drug-row__name {
  margin-bottom: 4px;
  font-size: 14px;
  font-weight: 600;
  color: #1e293b;
}
.dark .df-detail-drug-row__name {
  color: #e2e8f0;
}
.df-detail-drug-row__sub {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  font-size: 12px;
  color: #64748b;
}
.df-detail-drug-row__money {
  flex-shrink: 0;
  text-align: right;
}
.df-detail-drug-row__price {
  margin-bottom: 2px;
  font-size: 12px;
  color: #94a3b8;
}
.df-detail-drug-row__total {
  font-size: 16px;
  font-weight: 700;
  color: #2563eb;
}
.dark .df-detail-drug-row__total {
  color: #60a5fa;
}
</style>
