<script setup lang="ts">
import {
  Coin,
  DataAnalysis,
  Finished,
  Headset,
  OfficeBuilding,
  TrendCharts,
  UserFilled,
  Wallet,
  Warning,
} from '@element-plus/icons-vue';
import * as echarts from 'echarts';
import { computed, nextTick, onBeforeUnmount, onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { http, type PageResult } from '../api/http';
import { displayModality, displayModelName, displayOperation, displayProvider } from '../utils/display';

type Overview = {
  totalTenants?: number;
  activeTenants?: number;
  totalUsers?: number;
  todayNewTenants?: number;
  todayConsumedCredits?: number;
  todayRechargedCredits?: number;
};

type TrendPoint = {
  day: string;
  newTenants: number;
  consumedCredits: number;
  rechargedCredits: number;
};

type ProviderStats = {
  modelProvider: string;
  modelId: string;
  modelName: string;
  total: number;
  succeeded: number;
  failed: number;
  credits: number;
  failureRate: number;
};

type TaskStats = {
  taskType: string;
  total: number;
  succeeded: number;
  failed: number;
  successRate: number;
};

type TenantRow = {
  id: string;
  name: string;
  plan: string;
  balance: number;
  memberCount: number;
  projectCount: number;
  status: number;
};

type BillingRow = {
  id: string;
  tenantId: string;
  tenantName?: string;
  userName?: string;
  operation: string;
  operationLabel?: string;
  modelName: string;
  modelId?: string;
  credits: number;
  modality: string;
  success?: boolean;
  successLabel?: string;
  createdAt: string;
};

type ModulePage = {
  rows: Record<string, string>[];
};

const loading = ref(false);
const router = useRouter();
const overview = ref<Overview>({});
const trends = ref<TrendPoint[]>([]);
const providers = ref<ProviderStats[]>([]);
const tasks = ref<TaskStats[]>([]);
const tenants = ref<TenantRow[]>([]);
const recentRecords = ref<BillingRow[]>([]);
const recentPage = ref<PageResult<BillingRow>>({ records: [], total: 0, page: 1, size: 10 });
const recentQuery = reactive({ page: 1, size: 10 });
const recentPageSizes = [10, 20, 30];
const tenantAudits = ref<Record<string, string>[]>([]);
const warnings = ref<Record<string, string>[]>([]);
const tickets = ref<Record<string, string>[]>([]);

const trendEl = ref<HTMLDivElement>();
const providerEl = ref<HTMLDivElement>();
const taskEl = ref<HTMLDivElement>();
const tenantEl = ref<HTMLDivElement>();
const charts: echarts.ECharts[] = [];

const activeRate = computed(() => {
  const total = overview.value.totalTenants || 0;
  return total ? Math.round(((overview.value.activeTenants || 0) / total) * 1000) / 10 : 0;
});

const netCredits = computed(() => Number(overview.value.todayRechargedCredits || 0) - Number(overview.value.todayConsumedCredits || 0));
const pendingAudits = computed(() => tenantAudits.value.filter((row) => !['已通过', '已处理'].includes(row.status)).length);
const pendingWarnings = computed(() => warnings.value.filter((row) => !['已处理', '已关闭'].includes(row.status)).length);
const pendingTickets = computed(() => tickets.value.filter((row) => !['已处理', '已解决', '已关闭'].includes(row.status)).length);
const taskFailureCount = computed(() => tasks.value.reduce((sum, item) => sum + Number(item.failed || 0), 0));
const pendingTotal = computed(() => pendingAudits.value + pendingWarnings.value + pendingTickets.value);
const providerRows = computed(() => providers.value.filter((item) => Number(item.credits || 0) > 0));
const providerTotalCredits = computed(() => providerRows.value.reduce((sum, item) => sum + Number(item.credits || 0), 0));
const taskRows = computed(() => tasks.value.map((item) => ({ ...item, label: displayOperation(item.taskType) })));

const topTenants = computed(() => {
  return [...tenants.value]
    .sort((a, b) => Number(b.balance || 0) - Number(a.balance || 0))
    .slice(0, 5);
});

const primaryMetricCards = computed(() => [
  { label: '总租户', value: formatNumber(overview.value.totalTenants), hint: '平台企业总量', target: '/tenants', icon: OfficeBuilding },
  { label: '活跃租户', value: formatNumber(overview.value.activeTenants), hint: `活跃率 ${activeRate.value}%`, target: '/tenants', query: { status: '1' }, icon: TrendCharts },
  { label: '总用户', value: formatNumber(overview.value.totalUsers), hint: '企业成员账号', target: '/users', icon: UserFilled },
  { label: '今日新增', value: formatNumber(overview.value.todayNewTenants), hint: '新开户企业', target: '/tenant-audits', query: { status: '资料待审' }, icon: Finished },
]);

const heroKpiCards = computed(() => [
  { label: '今日充值', value: formatNumber(overview.value.todayRechargedCredits), hint: '充值入账积分', target: '/billing/records', query: { modality: 'RECHARGE' }, icon: Wallet },
  { label: '今日消费', value: formatNumber(overview.value.todayConsumedCredits), hint: '模型扣费积分', target: '/billing/records', query: { success: 'true' }, icon: Coin },
  { label: '今日净额', value: formatNumber(netCredits.value), hint: '充值减消费', target: '/billing/records', icon: DataAnalysis },
  { label: '待办事项', value: formatNumber(pendingTotal.value), hint: '审核 / 预警 / 工单', target: '/warnings', query: { status: '待处理' }, icon: Warning },
]);

const commandPills = computed(() => [
  { label: '活跃率', value: `${activeRate.value}%`, target: '/tenants', query: { status: '1' } },
  { label: '模型消耗', value: formatNumber(providerTotalCredits.value), target: '/billing/records' },
  { label: '失败任务', value: formatNumber(taskFailureCount.value), target: '/warnings', query: { keyword: '任务失败率' } },
]);

const operationCards = computed(() => [
  { label: '租户活跃率', value: `${activeRate.value}%`, hint: '正常企业 / 总企业', tone: 'blue', target: '/tenants', query: { status: '1' }, icon: TrendCharts },
  { label: '今日净充值', value: formatNumber(netCredits.value), hint: '充值减消费', tone: netCredits.value >= 0 ? 'green' : 'orange', target: '/billing/records', icon: Wallet },
  { label: '待入驻审核', value: pendingAudits.value, hint: '证照与法人核验', tone: pendingAudits.value ? 'orange' : 'green', target: '/tenant-audits', query: { status: '资料待审' }, icon: Finished },
  { label: '待处理预警', value: pendingWarnings.value, hint: '运营预警表', tone: pendingWarnings.value ? 'orange' : 'green', target: '/warnings', query: { status: '待处理' }, icon: Warning },
  { label: '待跟进工单', value: pendingTickets.value, hint: '客服工作台', tone: pendingTickets.value ? 'blue' : 'green', target: '/tickets', query: { status: '待响应' }, icon: Headset },
  { label: '失败任务', value: taskFailureCount.value, hint: 'AI 任务健康度', tone: taskFailureCount.value ? 'orange' : 'green', target: '/warnings', query: { keyword: '任务失败率' }, icon: DataAnalysis },
]);

function formatNumber(value?: number | string) {
  const numeric = Number(value || 0);
  return numeric.toLocaleString('zh-CN', { maximumFractionDigits: 1 });
}

function formatAxis(value: number) {
  if (Math.abs(value) >= 10000) return `${Math.round(value / 1000)}k`;
  if (Math.abs(value) >= 1000) return `${Math.round(value / 100) / 10}k`;
  return String(value);
}

function shortDate(value?: string) {
  return value ? value.slice(5, 10) : '-';
}

function safeRows(page?: ModulePage) {
  return Array.isArray(page?.rows) ? page.rows : [];
}

function providerName(item: ProviderStats) {
  return displayModelName(item.modelName, item.modelId) || '未知模型';
}

function providerMeta(item: ProviderStats) {
  return `${displayProvider(item.modelProvider)} · ${formatNumber(item.total)} 次调用`;
}

function percent(value?: number) {
  const total = providerTotalCredits.value;
  return total ? `${Math.round((Number(value || 0) / total) * 1000) / 10}%` : '0%';
}

function openTarget(target?: string, query?: Record<string, string | undefined>) {
  if (!target) return;
  router.push({ path: target, query });
}

async function loadRecentRecords() {
  recentPage.value = await http.get<PageResult<BillingRow>>('/billing/records', { params: recentQuery });
  recentRecords.value = recentPage.value.records || [];
}

function resetRecentPage() {
  recentQuery.page = 1;
  loadRecentRecords();
}

function disposeCharts() {
  while (charts.length) {
    charts.pop()?.dispose();
  }
}

function mountChart(el: HTMLDivElement | undefined, option: echarts.EChartsOption) {
  if (!el) return;
  const chart = echarts.init(el);
  chart.setOption(option);
  charts.push(chart);
}

async function load() {
  loading.value = true;
  try {
    const [overviewData, trendData, providerData, taskData, tenantPage, auditPage, warningPage, ticketPage] = await Promise.all([
      http.get<Overview>('/dashboard/overview'),
      http.get<TrendPoint[]>('/dashboard/trends?days=30'),
      http.get<ProviderStats[]>('/dashboard/providers'),
      http.get<TaskStats[]>('/dashboard/tasks'),
      http.get<PageResult<TenantRow>>('/tenants', { params: { page: 1, size: 100 } }),
      http.get<ModulePage>('/module-pages/tenantAudits'),
      http.get<ModulePage>('/module-pages/warnings'),
      http.get<ModulePage>('/module-pages/tickets'),
    ]);

    overview.value = overviewData;
    trends.value = trendData;
    providers.value = providerData;
    tasks.value = taskData;
    tenants.value = tenantPage.records || [];
    tenantAudits.value = safeRows(auditPage);
    warnings.value = safeRows(warningPage);
    tickets.value = safeRows(ticketPage);
    await loadRecentRecords();
    await nextTick();
    renderCharts();
  } finally {
    loading.value = false;
  }
}

function renderCharts() {
  disposeCharts();
  const axisColor = '#98a2b3';
  const tooltipStyle = {
    backgroundColor: 'rgba(255, 255, 255, 0.96)',
    borderColor: '#d9e2ef',
    borderWidth: 1,
    textStyle: { color: '#1d2939', fontWeight: 700 },
    extraCssText: 'box-shadow:0 18px 40px rgba(15,23,42,.12);border-radius:12px;',
  };
  const splitLine = { lineStyle: { color: '#edf1f7' } };
  const axisLine = { lineStyle: { color: '#d9e2ef' } };
  const grid = { left: 46, right: 24, top: 36, bottom: 48 };

  mountChart(trendEl.value, {
    color: ['#2f6bff', '#0f766e', '#f4b840'],
    tooltip: { trigger: 'axis', axisPointer: { type: 'cross', lineStyle: { color: '#b8c4d6' } }, ...tooltipStyle },
    legend: { bottom: 0, itemWidth: 10, itemHeight: 10, textStyle: { color: '#475467', fontWeight: 700 } },
    grid,
    xAxis: {
      type: 'category',
      data: trends.value.map((item) => shortDate(item.day)),
      axisLabel: { color: axisColor, margin: 12 },
      axisLine,
      axisTick: { show: false },
    },
    yAxis: { type: 'value', axisLabel: { color: axisColor, formatter: formatAxis }, splitLine, axisLine: { show: false } },
    series: [
      {
        name: '消费',
        type: 'bar',
        barWidth: 9,
        itemStyle: { borderRadius: [6, 6, 0, 0], color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: '#3f7bff' }, { offset: 1, color: '#8eb0ff' }]) },
        data: trends.value.map((item) => item.consumedCredits),
      },
      {
        name: '充值',
        type: 'line',
        smooth: true,
        symbolSize: 7,
        lineStyle: { width: 3 },
        areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: 'rgba(15,118,110,.18)' }, { offset: 1, color: 'rgba(15,118,110,0)' }]) },
        data: trends.value.map((item) => item.rechargedCredits),
      },
      { name: '新增租户', type: 'line', smooth: true, symbolSize: 6, lineStyle: { width: 2 }, data: trends.value.map((item) => item.newTenants) },
    ],
  });

  mountChart(providerEl.value, {
    color: ['#2f6bff', '#0f766e', '#8b5cf6', '#f4b840', '#ef6f6c'],
    tooltip: { trigger: 'item', formatter: '{b}<br/>积分 {c} · {d}%', ...tooltipStyle },
    legend: { show: false },
    graphic: [
      {
        type: 'text',
        left: 'center',
        top: '42%',
        style: {
          text: `${formatNumber(providerTotalCredits.value)}\n积分消耗`,
          align: 'center',
          fill: '#101828',
          fontSize: 18,
          fontWeight: 'bold',
          lineHeight: 24,
        },
      },
    ],
    series: [
      {
        name: '模型消耗',
        type: 'pie',
        radius: ['58%', '78%'],
        center: ['50%', '50%'],
        avoidLabelOverlap: true,
        label: { show: false },
        labelLine: { show: false },
        itemStyle: { borderColor: '#fff', borderWidth: 3 },
        data: providerRows.value.map((item) => ({ name: providerName(item), value: item.credits })),
      },
    ],
  });

  const taskRadarRows = taskRows.value.length
    ? taskRows.value
    : [{ label: '暂无任务', total: 0, succeeded: 0, failed: 0, successRate: 0, taskType: 'empty' }];
  mountChart(taskEl.value, {
    color: ['#0f766e', '#ef6f6c'],
    tooltip: {
      trigger: 'item',
      formatter: () => taskRadarRows
        .map((item) => `${item.label}<br/>成功率 ${Number(item.successRate || 0).toFixed(1)}% · 成功 ${item.succeeded} · 失败 ${item.failed}`)
        .join('<br/><br/>'),
      ...tooltipStyle,
    },
    radar: {
      center: ['50%', '50%'],
      radius: '64%',
      splitNumber: 4,
      indicator: taskRadarRows.map((item) => ({ name: item.label, max: 100 })),
      axisName: { color: '#475467', fontWeight: 700, fontSize: 12 },
      axisLine: { lineStyle: { color: '#d9e2ef' } },
      splitLine: { lineStyle: { color: '#e7edf6' } },
      splitArea: { areaStyle: { color: ['#ffffff', '#f8fbff'] } },
    },
    series: [
      {
        name: '任务成功率',
        type: 'radar',
        symbolSize: 5,
        lineStyle: { width: 3 },
        areaStyle: { color: 'rgba(15,118,110,.14)' },
        data: [{ value: taskRadarRows.map((item) => Number(item.successRate || 0)), name: '成功率' }],
      },
    ],
  });

  mountChart(tenantEl.value, {
    color: ['#2f6bff'],
    tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' }, ...tooltipStyle },
    grid: { left: 78, right: 22, top: 18, bottom: 28 },
    xAxis: { type: 'value', axisLabel: { color: axisColor, formatter: formatAxis }, splitLine, axisLine: { show: false } },
    yAxis: {
      type: 'category',
      data: topTenants.value.map((item) => item.name),
      axisLabel: { color: '#475467', width: 86, overflow: 'truncate', fontWeight: 700 },
      axisTick: { show: false },
      axisLine,
    },
    series: [
      {
        name: '余额',
        type: 'bar',
        barWidth: 14,
        itemStyle: { borderRadius: [0, 8, 8, 0], color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [{ offset: 0, color: '#2f6bff' }, { offset: 1, color: '#7ca2ff' }]) },
        data: topTenants.value.map((item) => item.balance),
      },
    ],
  });
}

function resizeCharts() {
  charts.forEach((chart) => chart.resize());
}

onMounted(() => {
  load();
  window.addEventListener('resize', resizeCharts);
});

onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeCharts);
  disposeCharts();
});
</script>

<template>
  <div v-loading="loading" class="dashboard-page">
    <section class="dashboard-command">
      <div class="dashboard-command-copy">
        <span class="dashboard-eyebrow">运营驾驶舱</span>
        <h1>数据大盘</h1>
        <p>把租户增长、计费入账、模型消耗、任务健康和运营待办集中到一屏，优先呈现需要立即判断的指标。</p>
        <div class="dashboard-command-pills">
          <button
            v-for="pill in commandPills"
            :key="pill.label"
            type="button"
            class="dashboard-command-pill"
            @click="openTarget(pill.target, pill.query)"
          >
            <span>{{ pill.label }}</span>
            <b>{{ pill.value }}</b>
          </button>
        </div>
      </div>
      <div class="dashboard-today-grid">
        <button
          v-for="card in heroKpiCards"
          :key="card.label"
          type="button"
          class="dashboard-today-card"
          @click="openTarget(card.target, card.query)"
        >
          <el-icon class="dashboard-card-icon"><component :is="card.icon" /></el-icon>
          <span>{{ card.label }}</span>
          <strong>{{ card.value }}</strong>
          <small>{{ card.hint }}</small>
        </button>
      </div>
    </section>

    <section class="dashboard-section">
      <div class="dashboard-section-head">
        <div>
          <b>核心规模</b>
          <span>租户、账号与今日开户</span>
        </div>
      </div>
      <div class="metric-grid dashboard-metrics">
        <div
          v-for="card in primaryMetricCards"
          :key="card.label"
          class="metric"
        >
          <span class="dashboard-card-label">
            <el-icon class="dashboard-card-icon"><component :is="card.icon" /></el-icon>
            <span>{{ card.label }}</span>
          </span>
          <button type="button" class="metric-action-number" :aria-label="`查看${card.label}`" @click="openTarget(card.target, card.query)">
            <strong>{{ card.value }}</strong>
          </button>
          <small>{{ card.hint }}</small>
          <button type="button" class="dashboard-more-link" :aria-label="`查看${card.label}更多数据`" title="查看更多" @click="openTarget(card.target, card.query)">
            <span class="visually-hidden">查看更多</span>
          </button>
        </div>
      </div>
    </section>

    <section class="dashboard-section">
      <div class="dashboard-section-head">
        <div>
          <b>运营健康</b>
          <span>异常、待办和资源净变化</span>
        </div>
      </div>
      <div class="ops-card-grid">
        <div
          v-for="card in operationCards"
          :key="card.label"
          class="ops-card"
          :class="`tone-${card.tone}`"
        >
          <span class="dashboard-card-label">
            <el-icon class="dashboard-card-icon"><component :is="card.icon" /></el-icon>
            <span>{{ card.label }}</span>
          </span>
          <button type="button" class="ops-action-number" :aria-label="`查看${card.label}`" @click="openTarget(card.target, card.query)">
            <strong>{{ card.value }}</strong>
          </button>
          <small>{{ card.hint }}</small>
          <button type="button" class="dashboard-more-link" :aria-label="`查看${card.label}更多数据`" title="查看更多" @click="openTarget(card.target, card.query)">
            <span class="visually-hidden">查看更多</span>
          </button>
        </div>
      </div>
    </section>

    <div class="panel-grid dashboard-chart-grid">
      <div class="panel dashboard-panel trend-panel">
        <div class="panel-title">
          <div><b>近 30 天资源与增长趋势</b><span>消费、充值与新增租户同屏观察</span></div>
          <button type="button" class="dashboard-panel-more" aria-label="查看更多计费记录" title="查看更多" @click="openTarget('/billing/records')">
            <span class="visually-hidden">查看更多</span>
          </button>
        </div>
        <div ref="trendEl" class="chart-box chart-lg" />
      </div>
      <div class="panel dashboard-panel model-panel">
        <div class="panel-title">
          <div><b>模型消耗占比</b><span>按模型维度汇总积分消耗</span></div>
          <button type="button" class="dashboard-panel-more" aria-label="查看更多模型消耗" title="查看更多" @click="openTarget('/billing/records')">
            <span class="visually-hidden">查看更多</span>
          </button>
        </div>
        <div ref="providerEl" class="chart-box model-chart-box" />
        <div class="model-consumption-list">
          <div v-for="item in providerRows" :key="`${item.modelProvider}-${item.modelId}`" class="model-consumption-row">
            <span>
              <b>{{ providerName(item) }}</b>
              <small>{{ providerMeta(item) }}</small>
            </span>
            <strong>{{ formatNumber(item.credits) }}</strong>
            <em>{{ percent(item.credits) }}</em>
          </div>
        </div>
      </div>
    </div>

    <div class="dashboard-lower-grid">
      <div class="panel dashboard-panel">
        <div class="panel-title">
          <div><b>任务健康度</b><span>按任务类型观察成功率与失败风险</span></div>
          <button type="button" class="dashboard-panel-more" aria-label="查看更多任务健康数据" title="查看更多" @click="openTarget('/warnings', { keyword: '任务失败率' })">
            <span class="visually-hidden">查看更多</span>
          </button>
        </div>
        <div ref="taskEl" class="chart-box chart-sm" />
      </div>
      <div class="panel dashboard-panel">
        <div class="panel-title">
          <div><b>企业余额排行</b><span>识别高价值与高消耗企业</span></div>
          <button type="button" class="dashboard-panel-more" aria-label="查看更多企业余额数据" title="查看更多" @click="openTarget('/tenants')">
            <span class="visually-hidden">查看更多</span>
          </button>
        </div>
        <div ref="tenantEl" class="chart-box chart-sm" />
      </div>
      <div class="panel dashboard-panel insight-panel">
        <div class="panel-title">
          <div><b>运营待办</b><span>预警与客服事项聚合</span></div>
          <button type="button" class="dashboard-panel-more" aria-label="查看更多运营待办" title="查看更多" @click="openTarget('/warnings', { status: '待处理' })">
            <span class="visually-hidden">查看更多</span>
          </button>
        </div>
        <div class="insight-list">
          <div v-for="row in tenantAudits.slice(0, 3)" :key="`audit-${row.id || row.company}`" class="insight-row">
            <span>入驻</span>
            <strong>{{ row.company || row.title || row.name }}</strong>
            <small>{{ row.status || row.risk || '-' }}</small>
          </div>
          <div v-for="row in warnings.slice(0, 3)" :key="`warning-${row.id || row.title}`" class="insight-row">
            <span>预警</span>
            <strong>{{ row.company || row.title || row.name }}</strong>
            <small>{{ row.status || row.level || '-' }}</small>
          </div>
          <div v-for="row in tickets.slice(0, 3)" :key="`ticket-${row.id || row.ticketNo}`" class="insight-row">
            <span>工单</span>
            <strong>{{ row.company || row.ticketNo || row.title }}</strong>
            <small>{{ row.status || row.priority || '-' }}</small>
          </div>
        </div>
      </div>
    </div>

    <div class="panel dashboard-panel billing-preview-panel">
      <div class="panel-title">
        <div><b>最新计费记录</b><span>逐笔展示充值入账、模型扣费、积分变化和成功状态</span></div>
        <button type="button" class="dashboard-panel-more" aria-label="查看全部计费记录" title="查看全部" @click="openTarget('/billing/records')">
          <span class="visually-hidden">查看全部</span>
        </button>
      </div>
      <el-table :data="recentRecords" row-key="id">
        <el-table-column prop="createdAt" label="时间" min-width="150" />
        <el-table-column prop="tenantName" label="企业租户" min-width="160" />
        <el-table-column label="计费动作" min-width="140">
          <template #default="{ row }">{{ row.operationLabel || displayOperation(row.operation) }}</template>
        </el-table-column>
        <el-table-column label="模型/资源" min-width="180">
          <template #default="{ row }">{{ displayModelName(row.modelName, row.modelId) }}</template>
        </el-table-column>
        <el-table-column prop="modality" label="类型" width="120">
          <template #default="{ row }"><el-tag effect="plain">{{ displayModality(row.modality) }}</el-tag></template>
        </el-table-column>
        <el-table-column prop="credits" label="积分变化" width="120">
          <template #default="{ row }"><b>{{ formatNumber(row.credits) }}</b></template>
        </el-table-column>
        <el-table-column prop="successLabel" label="结果" width="100">
          <template #default="{ row }">
            <el-tag :type="row.success === false ? 'danger' : 'success'" effect="plain">{{ row.successLabel || (row.success === false ? '失败' : '成功') }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="userName" label="操作用户" min-width="150" />
      </el-table>
      <el-pagination
        v-model:current-page="recentQuery.page"
        v-model:page-size="recentQuery.size"
        layout="total, sizes, prev, pager, next"
        :page-sizes="recentPageSizes"
        :total="recentPage.total"
        @current-change="loadRecentRecords"
        @size-change="resetRecentPage"
      />
    </div>
  </div>
</template>
