<script setup lang="ts">
import { ref, onMounted, reactive } from "vue";
import * as echarts from "echarts";
import { 
  getRepurchaseOverview, 
  getRepurchaseDistribution, 
  getRepurchaseTrend, 
  getRepurchaseUsers 
} from "@/api/statistics";

defineOptions({
  name: "RepurchaseStatistics"
});

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

const queryParams = reactive({
  page: 1,
  pageSize: 10,
  shopId: null as number | null,
  userLayer: "",
  minOrderCount: null as number | null,
  sortBy: "totalAmount",
  sortOrder: "desc"
});

const overviewData = ref({
  totalUsers: 0,
  newUsers: 0,
  repurchaseUsers: 0,
  repurchaseRate: 0,
  avgOrderAmount: 0,
  avgPurchaseCount: 0,
  ltv: 0
});

const tableData = ref([]);
const total = ref(0);

const layerChartRef = ref<HTMLElement | null>(null);
const intervalChartRef = ref<HTMLElement | null>(null);
const trendChartRef = ref<HTMLElement | null>(null);
let layerChart: echarts.ECharts | null = null;
let intervalChart: echarts.ECharts | null = null;
let trendChart: echarts.ECharts | null = null;

async function fetchOverview() {
  try {
    const params = {
      startDate: formatDate(dateRange.value[0]),
      endDate: formatDate(dateRange.value[1])
    };
    
    const { data } = await getRepurchaseOverview(params);
    overviewData.value = data;
  } catch (error) {
    console.error("获取复购概览失败:", error);
  }
}

async function fetchDistribution() {
  try {
    const params = {
      startDate: formatDate(dateRange.value[0]),
      endDate: formatDate(dateRange.value[1]),
      type: "layer"
    };
    
    const { data } = await getRepurchaseDistribution(params);
    initLayerChart(data.distribution);
    
    const intervalParams = {
      startDate: formatDate(dateRange.value[0]),
      endDate: formatDate(dateRange.value[1]),
      type: "interval"
    };
    
    const intervalRes = await getRepurchaseDistribution(intervalParams);
    initIntervalChart(intervalRes.data.distribution);
  } catch (error) {
    console.error("获取复购分布失败:", error);
  }
}

async function fetchTrend() {
  try {
    const params = {
      startDate: formatDate(dateRange.value[0]),
      endDate: formatDate(dateRange.value[1])
    };
    
    const { data } = await getRepurchaseTrend(params);
    initTrendChart(data);
  } catch (error) {
    console.error("获取复购趋势失败:", error);
  }
}

async function fetchUserList() {
  loading.value = true;
  try {
    const params = {
      ...queryParams,
      startDate: formatDate(dateRange.value[0]),
      endDate: formatDate(dateRange.value[1])
    };
    
    const { data } = await getRepurchaseUsers(params);
    tableData.value = data.list || [];
    total.value = data.total || 0;
  } catch (error) {
    console.error("获取用户复购数据失败:", error);
  } finally {
    loading.value = false;
  }
}

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

function initLayerChart(distribution: any) {
  if (!layerChartRef.value) return;
  
  if (layerChart) {
    layerChart.dispose();
  }
  
  layerChart = echarts.init(layerChartRef.value);
  
  const data = Object.entries(distribution || {}).map(([name, value]) => ({
    name,
    value
  }));
  
  const option: echarts.EChartsOption = {
    title: {
      text: "用户分层分布",
      left: "center",
      textStyle: { fontSize: 14, fontWeight: "normal" }
    },
    tooltip: {
      trigger: "item",
      formatter: "{a} <br/>{b}: {c} ({d}%)"
    },
    legend: {
      bottom: "5%",
      left: "center"
    },
    series: [
      {
        name: "用户层级",
        type: "pie",
        radius: ["40%", "70%"],
        avoidLabelOverlap: false,
        itemStyle: {
          borderRadius: 10,
          borderColor: "#fff",
          borderWidth: 2
        },
        label: {
          show: false,
          position: "center"
        },
        emphasis: {
          label: {
            show: true,
            fontSize: 16,
            fontWeight: "bold"
          }
        },
        labelLine: {
          show: false
        },
        data: data.map((item: any, index: number) => ({
          ...item,
          itemStyle: {
            color: ["#409eff", "#67c23a", "#e6a23c", "#f56c6c"][index % 4]
          }
        }))
      }
    ]
  };
  
  layerChart.setOption(option);
}

function initIntervalChart(distribution: any) {
  if (!intervalChartRef.value) return;
  
  if (intervalChart) {
    intervalChart.dispose();
  }
  
  intervalChart = echarts.init(intervalChartRef.value);
  
  const categories = Object.keys(distribution || {});
  const values = Object.values(distribution || {});
  
  const option: echarts.EChartsOption = {
    title: {
      text: "复购间隔分布",
      left: "center",
      textStyle: { fontSize: 14, fontWeight: "normal" }
    },
    tooltip: {
      trigger: "axis",
      axisPointer: { type: "shadow" }
    },
    grid: {
      left: "3%",
      right: "4%",
      bottom: "3%",
      containLabel: true
    },
    xAxis: {
      type: "category",
      data: categories
    },
    yAxis: {
      type: "value",
      name: "用户数"
    },
    series: [
      {
        name: "用户数",
        type: "bar",
        data: values,
        itemStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: "#83bff6" },
            { offset: 1, color: "#188df0" }
          ])
        }
      }
    ]
  };
  
  intervalChart.setOption(option);
}

function initTrendChart(data: any) {
  if (!trendChartRef.value) return;
  
  if (trendChart) {
    trendChart.dispose();
  }
  
  trendChart = echarts.init(trendChartRef.value);
  
  const option: echarts.EChartsOption = {
    title: {
      text: "复购率趋势",
      left: "center",
      textStyle: { fontSize: 14, fontWeight: "normal" }
    },
    tooltip: {
      trigger: "axis",
      backgroundColor: "rgba(255, 255, 255, 0.9)",
      borderColor: "#e5e7eb",
      borderWidth: 1
    },
    grid: {
      left: "3%",
      right: "4%",
      bottom: "3%",
      containLabel: true
    },
    xAxis: {
      type: "category",
      data: data.dates || [],
      axisLabel: {
        rotate: 45
      }
    },
    yAxis: {
      type: "value",
      name: "复购率(%)"
    },
    series: [
      {
        name: "复购率",
        type: "line",
        smooth: true,
        data: data.series?.[0]?.data || [],
        itemStyle: { color: "#722ed1" },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: "rgba(114, 46, 209, 0.3)" },
            { offset: 1, color: "rgba(114, 46, 209, 0.05)" }
          ])
        }
      }
    ]
  };
  
  trendChart.setOption(option);
}

function handleSearch() {
  queryParams.page = 1;
  fetchUserList();
}

function handleReset() {
  queryParams.shopId = null;
  queryParams.userLayer = "";
  queryParams.minOrderCount = null;
  queryParams.page = 1;
  fetchUserList();
}

function handleSortChange({ prop, order }: any) {
  queryParams.sortBy = prop || "totalAmount";
  queryParams.sortOrder = order === "ascending" ? "asc" : "desc";
  fetchUserList();
}

function handlePageChange(page: number) {
  queryParams.page = page;
  fetchUserList();
}

function handleSizeChange(size: number) {
  queryParams.pageSize = size;
  queryParams.page = 1;
  fetchUserList();
}

function handleDateChange() {
  fetchOverview();
  fetchDistribution();
  fetchTrend();
  fetchUserList();
}

function resizeCharts() {
  layerChart?.resize();
  intervalChart?.resize();
  trendChart?.resize();
}

function getUserLayerTagType(layer: string): string {
  switch (layer) {
    case "new": return "info";
    case "active": return "success";
    case "loyal": return "warning";
    case "churn": return "danger";
    default: return "";
  }
}

onMounted(() => {
  fetchOverview();
  fetchDistribution();
  fetchTrend();
  fetchUserList();
  window.addEventListener("resize", resizeCharts);
});
</script>

<template>
  <div class="repurchase-statistics">
    <el-card shadow="never" class="mb-4">
      <div class="flex items-center justify-between">
        <span class="text-lg font-medium">用户复购统计</span>
        <el-date-picker
          v-model="dateRange"
          type="daterange"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD"
          @change="handleDateChange"
        />
      </div>
    </el-card>

    <el-row :gutter="20" class="mb-6">
      <el-col :span="6">
        <el-card shadow="hover">
          <div class="stat-card">
            <div class="stat-icon bg-blue">
              <i class="ri:user-line"></i>
            </div>
            <div class="stat-info">
              <div class="stat-value">{{ overviewData.totalUsers?.toLocaleString() || 0 }}</div>
              <div class="stat-label">总用户数</div>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover">
          <div class="stat-card">
            <div class="stat-icon bg-green">
              <i class="ri:user-follow-line"></i>
            </div>
            <div class="stat-info">
              <div class="stat-value">{{ overviewData.repurchaseUsers?.toLocaleString() || 0 }}</div>
              <div class="stat-label">复购用户数</div>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover">
          <div class="stat-card">
            <div class="stat-icon bg-purple">
              <i class="ri:percent-line"></i>
            </div>
            <div class="stat-info">
              <div class="stat-value">{{ overviewData.repurchaseRate }}%</div>
              <div class="stat-label">复购率</div>
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="6">
        <el-card shadow="hover">
          <div class="stat-card">
            <div class="stat-icon bg-orange">
              <i class="ri:coins-line"></i>
            </div>
            <div class="stat-info">
              <div class="stat-value">¥{{ overviewData.ltv }}</div>
              <div class="stat-label">用户LTV</div>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="20" class="mb-6">
      <el-col :span="8">
        <el-card shadow="hover" class="chart-card">
          <div ref="layerChartRef" class="chart-container"></div>
        </el-card>
      </el-col>
      <el-col :span="8">
        <el-card shadow="hover" class="chart-card">
          <div ref="intervalChartRef" class="chart-container"></div>
        </el-card>
      </el-col>
      <el-col :span="8">
        <el-card shadow="hover" class="chart-card">
          <div ref="trendChartRef" class="chart-container"></div>
        </el-card>
      </el-col>
    </el-row>

    <el-card shadow="never">
      <template #header>
        <div class="flex items-center justify-between">
          <span class="font-medium">用户复购明细</span>
          <div class="flex items-center gap-2">
            <el-select v-model="queryParams.userLayer" placeholder="用户层级" clearable style="width: 120px">
              <el-option label="新用户" value="new" />
              <el-option label="活跃用户" value="active" />
              <el-option label="忠诚用户" value="loyal" />
              <el-option label="流失用户" value="churn" />
            </el-select>
            <el-input-number
              v-model="queryParams.minOrderCount"
              placeholder="最小购买次数"
              :min="1"
              controls-position="right"
              style="width: 140px"
            />
            <el-button type="primary" @click="handleSearch">搜索</el-button>
            <el-button @click="handleReset">重置</el-button>
          </div>
        </div>
      </template>
      
      <el-table :data="tableData" stripe v-loading="loading" @sort-change="handleSortChange">
        <el-table-column prop="nickname" label="用户昵称" width="120" show-overflow-tooltip />
        <el-table-column prop="phone" label="手机号" width="120" />
        <el-table-column prop="orderCount" label="购买次数" width="100" align="right" sortable="custom" />
        <el-table-column prop="totalAmount" label="累计消费(元)" width="120" align="right" sortable="custom">
          <template #default="{ row }">
            ¥{{ row.totalAmount?.toLocaleString() || 0 }}
          </template>
        </el-table-column>
        <el-table-column prop="avgOrderAmount" label="平均客单价" width="100" align="right">
          <template #default="{ row }">
            ¥{{ row.avgOrderAmount || 0 }}
          </template>
        </el-table-column>
        <el-table-column prop="firstOrderDate" label="首次下单" width="110" />
        <el-table-column prop="lastOrderDate" label="最近下单" width="110" />
        <el-table-column prop="repurchaseDays" label="复购间隔(天)" width="110" align="right" />
        <el-table-column prop="userLayerLabel" label="用户层级" width="100" align="center">
          <template #default="{ row }">
            <el-tag :type="getUserLayerTagType(row.userLayer)" size="small">
              {{ row.userLayerLabel }}
            </el-tag>
          </template>
        </el-table-column>
      </el-table>
      
      <div class="flex justify-end mt-4">
        <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"
          @size-change="handleSizeChange"
          @current-change="handlePageChange"
        />
      </div>
    </el-card>
  </div>
</template>

<style lang="scss" scoped>
.repurchase-statistics {
  padding: 20px;
  background-color: var(--el-bg-color-page);
  min-height: calc(100vh - 120px);
}

.stat-card {
  display: flex;
  align-items: center;
  
  .stat-icon {
    width: 50px;
    height: 50px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-right: 16px;
    
    i {
      font-size: 24px;
      color: white;
    }
    
    &.bg-blue { background: linear-gradient(135deg, #409eff, #337ecc); }
    &.bg-green { background: linear-gradient(135deg, #67c23a, #529b2e); }
    &.bg-purple { background: linear-gradient(135deg, #722ed1, #531dab); }
    &.bg-orange { background: linear-gradient(135deg, #fa8c16, #d46b08); }
  }
  
  .stat-info {
    flex: 1;
    
    .stat-value {
      font-size: 24px;
      font-weight: 600;
      color: var(--el-text-color-primary);
      margin-bottom: 4px;
    }
    
    .stat-label {
      font-size: 14px;
      color: var(--el-text-color-secondary);
    }
  }
}

.chart-card {
  height: 320px;
  
  :deep(.el-card__body) {
    padding: 20px;
    height: 100%;
  }
  
  .chart-container {
    width: 100%;
    height: 100%;
    min-height: 260px;
  }
}
</style>
