<script setup lang="ts">
import { ref, onMounted, onUnmounted, reactive } from "vue";
import * as echarts from "echarts";
import { getProfitOverview, getProfitList, getProfitTrend, getProfitWarning } from "@/api/statistics";
import type { EChartsOption } from "echarts";

defineOptions({
  name: "ProfitStatistics"
});

const loading = ref(false);
const dateRange = ref<[Date, Date]>([
  new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
  new Date()
]);
const activeShortcut = ref("30d");

const shortcuts = [
  { key: "today", label: "今日" },
  { key: "week", label: "本周" },
  { key: "month", label: "本月" },
  { key: "30d", label: "近30天" }
];

const compareOptions = [
  { value: "", label: "无对比" },
  { value: "yoy", label: "同比" },
  { value: "mom", label: "环比" }
];

const queryParams = reactive({
  page: 1,
  pageSize: 10,
  keyword: "",
  province: "",
  city: "",
  shopId: null as number | null,
  compareType: "",
  sortBy: "netProfit",
  sortOrder: "desc"
});

const overviewData = ref({
  salesAmount: 0,
  costAmount: 0,
  grossProfit: 0,
  grossProfitRate: 0,
  refundAmount: 0,
  refundRate: 0,
  netProfit: 0,
  netProfitRate: 0
});

const tableData = ref<any[]>([]);
const total = ref(0);
const warningData = ref<any[]>([]);

const profitChartRef = ref<HTMLElement | null>(null);
const warningChartRef = ref<HTMLElement | null>(null);
let profitChart: echarts.ECharts | null = null;
let warningChart: echarts.ECharts | null = null;

function formatDate(date: Date): string { return date.toISOString().split("T")[0]; }

function setDateShortcut(type: string) {
  activeShortcut.value = type;
  const today = new Date(); today.setHours(23, 59, 59, 999);
  let start: Date;
  switch (type) {
    case "today": start = new Date(); start.setHours(0, 0, 0, 0); break;
    case "week": start = new Date(today); start.setDate(today.getDate() - 6); start.setHours(0, 0, 0, 0); break;
    case "month": start = new Date(today.getFullYear(), today.getMonth(), 1); break;
    case "30d": default: start = new Date(today); start.setDate(today.getDate() - 29); start.setHours(0, 0, 0, 0); break;
  }
  dateRange.value = [start, today];
  fetchAll();
}

function handleDateChange() { activeShortcut.value = ""; fetchAll(); }

function fetchAll() {
  fetchOverview();
  fetchProfitList();
  fetchProfitTrend();
  fetchWarning();
}

async function fetchOverview() {
  try {
    const params: any = { startDate: formatDate(dateRange.value[0]), endDate: formatDate(dateRange.value[1]) };
    if (queryParams.compareType) params.compareType = queryParams.compareType;
    const res = await getProfitOverview(params);
    if (res.code === 200 && res.data) overviewData.value = res.data;
  } catch (e) { console.error(e); }
}

async function fetchProfitList() {
  loading.value = true;
  try {
    const params: any = { ...queryParams, startDate: formatDate(dateRange.value[0]), endDate: formatDate(dateRange.value[1]) };
    const res = await getProfitList(params);
    if (res.code === 200 && res.data) {
      tableData.value = res.data.list || [];
      total.value = Number(res.data.total) || 0;
    }
  } catch (e) { console.error(e); } finally { loading.value = false; }
}

async function fetchProfitTrend() {
  try {
    const params: any = { startDate: formatDate(dateRange.value[0]), endDate: formatDate(dateRange.value[1]) };
    if (queryParams.compareType) params.compareType = queryParams.compareType;
    const res = await getProfitTrend(params);
    if (res.code === 200 && res.data) initProfitChart(res.data);
  } catch (e) { console.error(e); }
}

async function fetchWarning() {
  try {
    const params = { startDate: formatDate(dateRange.value[0]), endDate: formatDate(dateRange.value[1]), type: "low" };
    const res = await getProfitWarning(params);
    if (res.code === 200 && res.data) { warningData.value = res.data; initWarningChart(); }
  } catch (e) { console.error(e); }
}

function initProfitChart(data: any) {
  if (!profitChartRef.value) return;
  profitChart?.dispose();
  profitChart = echarts.init(profitChartRef.value);
  const option: EChartsOption = {
    tooltip: { trigger: "axis", backgroundColor: "#fff", borderColor: "#e5e7eb", textStyle: { color: "#333" } },
    grid: { left: "3%", right: "4%", bottom: "5%", top: "8%", containLabel: true },
    xAxis: { type: "category", data: data.dates || [], axisLabel: { rotate: 45, fontSize: 11 } },
    yAxis: { type: "value", name: "利润(元)", axisLabel: { formatter: (v: number) => v >= 10000 ? (v / 10000).toFixed(1) + "万" : String(v) } },
    series: [{
      name: "利润", type: "line", smooth: true, data: data.series?.[0]?.data || [], symbol: "circle", symbolSize: 4,
      lineStyle: { color: "#67c23a", width: 2 },
      areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: "rgba(103,194,58,0.2)" }, { offset: 1, color: "rgba(103,194,58,0.02)" }]) }
    }]
  };
  profitChart.setOption(option);
}

function initWarningChart() {
  if (!warningChartRef.value || warningData.value.length === 0) return;
  warningChart?.dispose();
  warningChart = echarts.init(warningChartRef.value);
  const list = [...warningData.value].slice(0, 10).reverse();
  const option: EChartsOption = {
    tooltip: { trigger: "axis", axisPointer: { type: "shadow" }, formatter: (p: any) => `${p[0].name}<br/>净利润: ¥${(p[0].value ?? 0).toLocaleString()}` },
    grid: { left: "3%", right: "8%", bottom: "3%", top: "8%", containLabel: true },
    xAxis: { type: "value", name: "净利润(元)" },
    yAxis: { type: "category", data: list.map((i: any) => i.shopName), axisLabel: { width: 100, overflow: "truncate" } },
    series: [{
      name: "净利润", type: "bar", data: list.map((i: any) => i.netProfit),
      itemStyle: { borderRadius: [0, 4, 4, 0], color: (p: any) => p.value >= 0 ? "#67c23a" : "#f56c6c" }
    }]
  };
  warningChart.setOption(option);
}

function handleSearch() { queryParams.page = 1; fetchProfitList(); }
function handleReset() { queryParams.keyword = ""; queryParams.province = ""; queryParams.city = ""; queryParams.shopId = null; queryParams.compareType = ""; queryParams.page = 1; fetchAll(); }
function handleSortChange({ prop, order }: any) { queryParams.sortBy = prop || "netProfit"; queryParams.sortOrder = order === "ascending" ? "asc" : "desc"; fetchProfitList(); }
function handlePageChange(page: number) { queryParams.page = page; fetchProfitList(); }
function handleSizeChange(size: number) { queryParams.pageSize = size; queryParams.page = 1; fetchProfitList(); }
function handleCompareChange() { fetchOverview(); fetchProfitList(); fetchProfitTrend(); }

function resizeCharts() { profitChart?.resize(); warningChart?.resize(); }

onMounted(() => {
  fetchAll();
  window.addEventListener("resize", resizeCharts);
});
onUnmounted(() => {
  window.removeEventListener("resize", resizeCharts);
  profitChart?.dispose();
  warningChart?.dispose();
});
</script>

<template>
  <div class="profit-statistics">
    <div class="toolbar">
      <h2 class="page-title">门店利润报表</h2>
      <div class="toolbar-right">
        <div class="date-shortcuts">
          <el-button v-for="s in shortcuts" :key="s.key" :type="activeShortcut === s.key ? 'primary' : 'default'" size="small" @click="setDateShortcut(s.key)">{{ s.label }}</el-button>
        </div>
        <el-date-picker v-model="dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" size="small" @change="handleDateChange" />
      </div>
    </div>

    <div v-loading="loading" class="page-body">
      <el-row :gutter="16" class="kpi-row">
        <el-col :xs="12" :sm="6" :lg="4">
          <div class="kpi-card kpi-blue"><div class="kpi-label">销售收入</div><div class="kpi-value">¥{{ (overviewData.salesAmount || 0).toLocaleString() }}</div></div>
        </el-col>
        <el-col :xs="12" :sm="6" :lg="4">
          <div class="kpi-card kpi-red"><div class="kpi-label">销售成本</div><div class="kpi-value">¥{{ (overviewData.costAmount || 0).toLocaleString() }}</div></div>
        </el-col>
        <el-col :xs="12" :sm="6" :lg="4">
          <div class="kpi-card kpi-green"><div class="kpi-label">毛利润</div><div class="kpi-value">¥{{ (overviewData.grossProfit || 0).toLocaleString() }}</div><div class="kpi-sub">毛利率 {{ overviewData.grossProfitRate || 0 }}%</div></div>
        </el-col>
        <el-col :xs="12" :sm="6" :lg="4">
          <div class="kpi-card kpi-purple"><div class="kpi-label">净利润</div><div class="kpi-value">¥{{ (overviewData.netProfit || 0).toLocaleString() }}</div><div class="kpi-sub">净利率 {{ overviewData.netProfitRate || 0 }}%</div></div>
        </el-col>
        <el-col :xs="12" :sm="6" :lg="4">
          <div class="kpi-card kpi-orange"><div class="kpi-label">退款金额</div><div class="kpi-value">¥{{ (overviewData.refundAmount || 0).toLocaleString() }}</div><div class="kpi-sub">退款率 {{ overviewData.refundRate || 0 }}%</div></div>
        </el-col>
        <el-col :xs="12" :sm="6" :lg="4">
          <div class="kpi-card kpi-cyan">
            <div class="kpi-label">对比周期</div>
            <el-select v-model="queryParams.compareType" size="small" style="width: 100%;" @change="handleCompareChange">
              <el-option v-for="o in compareOptions" :key="o.value" :label="o.label" :value="o.value" />
            </el-select>
          </div>
        </el-col>
      </el-row>

      <el-row :gutter="16" class="chart-row">
        <el-col :span="14">
          <div class="chart-box"><div class="chart-title">利润趋势</div><div ref="profitChartRef" class="chart-container"></div></div>
        </el-col>
        <el-col :span="10">
          <div class="chart-box"><div class="chart-title">低利润预警门店</div><div ref="warningChartRef" class="chart-container"></div></div>
        </el-col>
      </el-row>

      <div class="table-box">
        <div class="table-header">
          <span class="table-title">门店利润明细</span>
          <div class="table-actions">
            <el-input v-model="queryParams.keyword" placeholder="门店名称" clearable size="small" style="width: 160px;" @keyup.enter="handleSearch" @clear="handleSearch" />
            <el-button type="primary" size="small" @click="handleSearch">搜索</el-button>
            <el-button size="small" @click="handleReset">重置</el-button>
          </div>
        </div>
        <el-table :data="tableData" stripe v-loading="loading" @sort-change="handleSortChange">
          <el-table-column prop="shopName" label="门店" min-width="130" fixed="left" show-overflow-tooltip />
          <el-table-column prop="province" label="省份" width="80" />
          <el-table-column prop="city" label="城市" width="80" />
          <el-table-column prop="deviceCount" label="设备数" width="75" align="right" />
          <el-table-column prop="salesAmount" label="销售收入" width="120" align="right" sortable="custom">
            <template #default="{ row }">¥{{ (row.salesAmount || 0).toLocaleString() }}</template>
          </el-table-column>
          <el-table-column prop="costAmount" label="销售成本" width="120" align="right">
            <template #default="{ row }">¥{{ (row.costAmount || 0).toLocaleString() }}</template>
          </el-table-column>
          <el-table-column prop="grossProfit" label="毛利润" width="110" align="right" sortable="custom">
            <template #default="{ row }"><span :style="{ color: (row.grossProfit || 0) >= 0 ? '#52c41a' : '#f5222d' }">¥{{ (row.grossProfit || 0).toLocaleString() }}</span></template>
          </el-table-column>
          <el-table-column prop="grossProfitRate" label="毛利率" width="80" align="right">
            <template #default="{ row }"><span :style="{ color: (row.grossProfitRate || 0) >= 0 ? '#52c41a' : '#f5222d' }">{{ row.grossProfitRate || 0 }}%</span></template>
          </el-table-column>
          <el-table-column prop="netProfit" label="净利润" width="110" align="right" sortable="custom">
            <template #default="{ row }"><span :style="{ color: (row.netProfit || 0) >= 0 ? '#52c41a' : '#f5222d' }">¥{{ (row.netProfit || 0).toLocaleString() }}</span></template>
          </el-table-column>
          <el-table-column prop="netProfitRate" label="净利率" width="80" align="right">
            <template #default="{ row }"><span :style="{ color: (row.netProfitRate || 0) >= 0 ? '#52c41a' : '#f5222d' }">{{ row.netProfitRate || 0 }}%</span></template>
          </el-table-column>
          <el-table-column prop="deviceProfit" label="单设备利润" width="110" align="right">
            <template #default="{ row }">¥{{ (row.deviceProfit || 0).toLocaleString() }}</template>
          </el-table-column>
          <el-table-column prop="yoyGrowth" label="同比增长" width="90" align="right">
            <template #default="{ row }">
              <span v-if="row.yoyGrowth != null" :style="{ color: (row.yoyGrowth || 0) >= 0 ? '#52c41a' : '#f5222d' }">{{ row.yoyGrowth }}%</span>
              <span v-else style="color: #c0c4cc;">--</span>
            </template>
          </el-table-column>
          <el-table-column prop="momGrowth" label="环比增长" width="90" align="right">
            <template #default="{ row }">
              <span v-if="row.momGrowth != null" :style="{ color: (row.momGrowth || 0) >= 0 ? '#52c41a' : '#f5222d' }">{{ row.momGrowth }}%</span>
              <span v-else style="color: #c0c4cc;">--</span>
            </template>
          </el-table-column>
        </el-table>
        <div class="table-footer">
          <el-pagination
            v-model:current-page="queryParams.page"
            v-model:page-size="queryParams.pageSize"
            :page-sizes="[10, 20, 50, 100]"
            :total="total"
            layout="total, sizes, prev, pager, next, jumper"
            background small
            @size-change="handleSizeChange"
            @current-change="handlePageChange"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.profit-statistics {
  padding: 16px 20px;
  background-color: #f5f7fa;
  min-height: calc(100vh - 120px);
}

.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  flex-wrap: wrap;
  gap: 12px;

  .page-title {
    margin: 0;
    font-size: 18px;
    font-weight: 600;
    color: #1d2129;
  }

  .toolbar-right {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
  }

  .date-shortcuts {
    display: flex;
    gap: 4px;
  }
}

.page-body { min-height: 400px; }

.kpi-row { margin-bottom: 12px; }

.kpi-card {
  background: #fff;
  border-radius: 8px;
  padding: 16px 20px;
  height: 100%;
  border-left: 4px solid #409eff;
  transition: box-shadow 0.2s;

  &:hover { box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); }

  &.kpi-blue { border-left-color: #409eff; }
  &.kpi-red { border-left-color: #f56c6c; }
  &.kpi-green { border-left-color: #67c23a; }
  &.kpi-purple { border-left-color: #722ed1; }
  &.kpi-orange { border-left-color: #fa8c16; }
  &.kpi-cyan { border-left-color: #13c2c2; }

  .kpi-label {
    font-size: 13px;
    color: #86909c;
    margin-bottom: 6px;
  }

  .kpi-value {
    font-size: 22px;
    font-weight: 700;
    color: #1d2129;
    line-height: 1.2;
  }

  .kpi-sub {
    font-size: 12px;
    color: #86909c;
    margin-top: 4px;
  }
}

.chart-row { margin-bottom: 12px; }

.chart-box {
  background: #fff;
  border-radius: 8px;
  padding: 16px;
  height: 380px;

  .chart-title {
    font-size: 14px;
    font-weight: 600;
    color: #1d2129;
    margin-bottom: 12px;
  }

  .chart-container {
    width: 100%;
    height: calc(100% - 30px);
  }
}

.table-box {
  background: #fff;
  border-radius: 8px;
  padding: 16px;

  .table-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
  }

  .table-title {
    font-size: 14px;
    font-weight: 600;
    color: #1d2129;
  }

  .table-actions {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .table-footer {
    display: flex;
    justify-content: flex-end;
    margin-top: 16px;
  }
}

@media (max-width: 768px) {
  .kpi-value { font-size: 18px !important; }
  .chart-box { height: 280px; }
}
</style>
