import type { EChartsOption } from '../../components/ECharts';
import {
  attendanceLabelMap,
  COLORS,
  type AttendanceTrendRow,
  type ClassAttendanceRank,
  type ClassroomOccupancy,
  type DashboardStats,
  type ExpenseByTypeRow,
  type GanttRoom,
  type IncomeTrendRow,
} from './Dashboard.types';

export function buildAttendanceRingOption(stats: DashboardStats | null): EChartsOption {
  return {
    tooltip: { trigger: 'item' },
    legend: { bottom: 0 },
    series: [
      {
        type: 'pie',
        radius: ['40%', '70%'],
        center: ['50%', '45%'],
        data: Object.entries(stats?.attendanceByStatus ?? {}).map(([status, count]) => ({
          name: attendanceLabelMap[status] ?? status,
          value: count,
        })),
        itemStyle: { borderRadius: 4, borderColor: '#fff', borderWidth: 2 },
      },
    ],
    color: COLORS,
  };
}

export function buildRoomRankingBarOption(
  roomRanking: Array<{ roomNumber: string; total: string }>,
): EChartsOption {
  return {
    tooltip: {},
    grid: { left: 80, right: 20, bottom: 30, top: 10 },
    xAxis: { type: 'value' },
    yAxis: {
      type: 'category',
      data: roomRanking.map((r) => r.roomNumber).reverse(),
      inverse: false,
    },
    series: [
      {
        type: 'bar',
        data: roomRanking.map((r) => Number(r.total)).reverse(),
        itemStyle: { color: '#007AFF', borderRadius: [0, 4, 4, 0] },
      },
    ],
  };
}

export function buildClassRankingOption(
  rows: ClassAttendanceRank[],
  color: string,
): EChartsOption {
  return {
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      valueFormatter: (v: number) => `${v}%`,
    },
    grid: { left: 80, right: 30, bottom: 30, top: 10 },
    xAxis: { type: 'value', max: 100, axisLabel: { formatter: '{value}%' } },
    yAxis: {
      type: 'category',
      data: rows.map((r) => r.className),
      inverse: true,
    },
    series: [
      {
        type: 'bar',
        data: rows.map((r) => r.rate),
        itemStyle: { color, borderRadius: [0, 4, 4, 0] },
        label: { show: true, position: 'right', formatter: '{c}%' },
      },
    ],
  };
}

export function buildAttendanceLineOption(rows: AttendanceTrendRow[]): EChartsOption {
  return {
    tooltip: { trigger: 'axis' },
    grid: { left: 50, right: 20, bottom: 30, top: 10 },
    xAxis: {
      type: 'category',
      data: rows.map((d) => d.date),
      axisLabel: { rotate: 45, fontSize: 10 },
    },
    yAxis: { type: 'value', min: 0, max: 100, axisLabel: { formatter: '{value}%' } },
    series: [
      {
        type: 'line',
        data: rows.map((d) => parseFloat(d.rate) || 0),
        smooth: true,
        lineStyle: { color: '#007AFF', width: 2 },
        itemStyle: { color: '#007AFF' },
        areaStyle: { color: 'rgba(0,122,255,0.1)' },
      },
    ],
  };
}

export function buildIncomeLineOption(rows: IncomeTrendRow[]): EChartsOption {
  return {
    tooltip: { trigger: 'axis', valueFormatter: (v: number) => `¥${v.toLocaleString()}` },
    grid: { left: 70, right: 20, bottom: 30, top: 10 },
    xAxis: {
      type: 'category',
      data: rows.map((d) => d.month),
    },
    yAxis: {
      type: 'value',
      axisLabel: { formatter: (v: number) => `¥${(v / 10000).toFixed(0)}万` },
    },
    series: [
      {
        type: 'line',
        data: rows.map((d) => d.amount),
        smooth: true,
        lineStyle: { color: '#34C759', width: 2 },
        itemStyle: { color: '#34C759' },
        areaStyle: { color: 'rgba(52,199,89,0.1)' },
      },
    ],
  };
}

export function buildExpensePieOption(
  rows: ExpenseByTypeRow[],
  expenseTypeMap: Record<string, string>,
): EChartsOption {
  return {
    tooltip: { trigger: 'item' },
    legend: { bottom: 0 },
    color: COLORS,
    series: [
      {
        type: 'pie',
        radius: ['40%', '70%'],
        center: ['50%', '45%'],
        data: rows.map((e) => ({
          name: expenseTypeMap[e.type] ?? e.type,
          value: Number(e.total),
        })),
      },
    ],
  };
}

export function buildClassroomHeatmapOption(
  classroomOccupancy: ClassroomOccupancy[],
): EChartsOption {
  return {
    tooltip: {
      formatter: (p: {
        name: string;
        data: { scheduleDays: number; rentalCount: number; occupancy: number };
      }) =>
        `${p.name}<br/>排课: ${p.data.scheduleDays}天 租赁: ${p.data.rentalCount}个 占用率: ${(p.data.occupancy * 100).toFixed(0)}%`,
    },
    grid: { left: 100, right: 20, bottom: 30, top: 10 },
    xAxis: { type: 'value', max: 1 },
    yAxis: {
      type: 'category',
      data: classroomOccupancy.map((r) => r.name),
      inverse: true,
    },
    visualMap: {
      min: 0,
      max: 1,
      orient: 'horizontal',
      left: 'center',
      bottom: 0,
      inRange: {
        color: ['#e6f4ff', '#91caff', '#40a9ff', '#0050b3', '#002c8c'],
      },
    },
    series: [
      {
        type: 'bar',
        data: classroomOccupancy.map((r) => ({
          name: r.name,
          value: r.occupancy,
          scheduleDays: r.scheduleDays,
          rentalCount: r.rentalCount,
          occupancy: r.occupancy,
        })),
        itemStyle: { borderRadius: [0, 4, 4, 0] },
        label: {
          show: true,
          position: 'right',
          formatter: (p: { data: { occupancy: number } }) =>
            `${(p.data.occupancy * 100).toFixed(0)}%`,
        },
      },
    ],
  };
}

export function buildGanttOption(ganttData: GanttRoom[]): EChartsOption {
  return {
    tooltip: {
      formatter: (p: { data: { name: string; value: [string, string, string, boolean] } }) =>
        `${p.data.name}<br/>入住: ${p.data.value[1]}<br/>退宿: ${p.data.value[2]}`,
    },
    grid: { left: 100, right: 30, bottom: 40, top: 20 },
    xAxis: { type: 'time' },
    yAxis: { type: 'category', data: ganttData.map((r) => r.roomNumber), inverse: true },
    dataZoom: [
      { type: 'slider', xAxisIndex: 0, bottom: 10, height: 20 },
      { type: 'inside', xAxisIndex: 0 },
    ],
    series: [
      {
        type: 'custom',
        renderItem: (
          _params: unknown,
          api: {
            value: (i: number) => string | boolean;
            coord: (p: [string | number, string | number]) => [number, number];
            size: (p: [number, number]) => [number, number];
          },
        ) => {
          const cat = String(api.value(0));
          const startDate = String(api.value(1));
          const endDate = String(api.value(2));
          const isActive = Boolean(api.value(3));
          const start = api.coord([startDate, cat]);
          const end = api.coord([endDate, cat]);
          const height = api.size([0, 1])[1] * 0.6;
          const rectShape = {
            x: start[0],
            y: start[1] - height / 2,
            width: Math.max(end[0] - start[0], 2),
            height,
          };
          return {
            type: 'rect' as const,
            shape: rectShape,
            style: { fill: isActive ? '#34C759' : '#FF9500', stroke: '#fff', lineWidth: 1 },
          };
        },
        encode: { x: [1, 2], y: 0 },
        data: ganttData.flatMap((r) =>
          (r.occupancies || []).map((o) => ({
            name: o.studentName,
            value: [
              r.roomNumber,
              o.checkInDate,
              o.checkOutDate || new Date().toISOString().slice(0, 10),
              !o.checkOutDate,
            ] as [string, string, string, boolean],
          })),
        ),
      },
    ],
  };
}
