"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import {
  Alert,
  Box,
  Button,
  CircularProgress,
  Grid,
  MenuItem,
  Paper,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TextField,
  Typography,
} from "@mui/material";
import type { ApexOptions } from "apexcharts";
import dayjs from "dayjs";
import * as XLSX from "xlsx-js-style";
import {
  CompletedDoPickOrderResponse,
  fetchCompletedDoPickOrdersAll,
  fetchCompletedDoPickOrdersWorkbenchAll,
} from "@/app/api/pickOrder/actions";
import SafeApexCharts from "@/components/charts/SafeApexCharts";

type FloorFilter = "all" | "2/F" | "4/F";

type DailySummaryRow = {
  date: string;
  floor2F: number;
  floor4F: number;
  truckX: number;
  total: number;
};

type Props = {
  mode?: "normal" | "workbench";
};

const FinishedGoodCartonDashboardTab: React.FC<Props> = ({ mode = "normal" }) => {
  const [floor, setFloor] = useState<FloorFilter>("all");
  const [date, setDate] = useState<string>(dayjs().format("YYYY-MM-DD"));
  const [loading, setLoading] = useState(false);
  const [isExporting, setIsExporting] = useState(false);
  const [error, setError] = useState<string>("");
  const [records, setRecords] = useState<CompletedDoPickOrderResponse[]>([]);

  const loadData = useCallback(async () => {
    setLoading(true);
    setError("");
    try {
      const data =
        mode === "workbench"
          ? await fetchCompletedDoPickOrdersWorkbenchAll(
              date ? { targetDate: date } : undefined,
            )
          : await fetchCompletedDoPickOrdersAll(
              date ? { targetDate: date } : undefined,
            );
      setRecords(data);
    } catch (err) {
      console.error("Failed to load finished good carton dashboard data", err);
      setError("載入成品出倉出箱數量失敗，請稍後再試。");
      setRecords([]);
    } finally {
      setLoading(false);
    }
  }, [date, mode]);

  useEffect(() => {
    loadData();
  }, [loadData]);

  const rows = useMemo<DailySummaryRow[]>(() => {
    const filtered =
      floor === "all" ? records : records.filter((record) => record.storeId === floor);

    const summary = new Map<string, DailySummaryRow>();

    filtered.forEach((record) => {
      const day = dayjs(record.deliveryDate).isValid()
        ? dayjs(record.deliveryDate).format("YYYY-MM-DD")
        : "-";
      const cartonQty = Number(record.numberOfCartons ?? 0);

      const current = summary.get(day) ?? {
        date: day,
        floor2F: 0,
        floor4F: 0,
        truckX: 0,
        total: 0,
      };

      if (record.storeId === "2/F") {
        current.floor2F += cartonQty;
      }
      if (record.storeId === "4/F") {
        current.floor4F += cartonQty;
      }
      if (String(record.truckLanceCode ?? "").trim() === "車線-X") {
        current.truckX += cartonQty;
      }

      current.total += cartonQty;
      summary.set(day, current);
    });

    return Array.from(summary.values()).sort((a, b) => b.date.localeCompare(a.date));
  }, [records, floor]);

  const chartOptions = useMemo<ApexOptions>(
    () => ({
      chart: {
        type: "bar",
        toolbar: { show: false },
      },
      colors: ["#1976d2", "#9c27b0", "#ff9800", "#2e7d32"],
      dataLabels: { enabled: false },
      stroke: { show: true, width: 1, colors: ["transparent"] },
      plotOptions: {
        bar: {
          horizontal: false,
          borderRadius: 3,
          columnWidth: "55%",
        },
      },
      xaxis: {
        categories: rows.map((row) => row.date),
        title: { text: "日期" },
      },
      yaxis: {
        title: { text: "箱數" },
        labels: {
          formatter: (val) => Number(val || 0).toLocaleString("zh-HK"),
        },
      },
      tooltip: {
        y: {
          formatter: (val) => `${Number(val || 0).toLocaleString("zh-HK")} 箱`,
        },
      },
      legend: {
        position: "top",
      },
      noData: {
        text: "沒有圖表資料",
      },
    }),
    [rows],
  );

  const chartSeries = useMemo(
    () => [
      { name: "2/F", data: rows.map((row) => row.floor2F) },
      { name: "4/F", data: rows.map((row) => row.floor4F) },
      { name: "車線-X", data: rows.map((row) => row.truckX) },
      { name: "總數", data: rows.map((row) => row.total) },
    ],
    [rows],
  );

  const summary = useMemo(() => {
    return rows.reduce(
      (acc, row) => {
        acc.floor2F += row.floor2F;
        acc.floor4F += row.floor4F;
        acc.truckX += row.truckX;
        acc.total += row.total;
        return acc;
      },
      { floor2F: 0, floor4F: 0, truckX: 0, total: 0 },
    );
  }, [rows]);

  const buildDailyRowsFromRecords = useCallback(
    (
      sourceRecords: CompletedDoPickOrderResponse[],
      startDate: dayjs.Dayjs,
      endDate: dayjs.Dayjs,
      selectedFloor: FloorFilter,
    ): DailySummaryRow[] => {
      const summaryMap = new Map<string, DailySummaryRow>();
      const start = startDate.startOf("day");
      const end = endDate.endOf("day");

      sourceRecords.forEach((record) => {
        if (selectedFloor !== "all" && record.storeId !== selectedFloor) {
          return;
        }

        const deliveryDay = dayjs(record.deliveryDate, ["YYYY-MM-DD", "YYYYMMDD"], true);
        if (!deliveryDay.isValid() || deliveryDay.isBefore(start) || deliveryDay.isAfter(end)) {
          return;
        }

        const dayKey = deliveryDay.format("YYYY-MM-DD");
        const cartonQty = Number(record.numberOfCartons ?? 0);
        const current = summaryMap.get(dayKey) ?? {
          date: dayKey,
          floor2F: 0,
          floor4F: 0,
          truckX: 0,
          total: 0,
        };

        if (record.storeId === "2/F") current.floor2F += cartonQty;
        if (record.storeId === "4/F") current.floor4F += cartonQty;
        if (String(record.truckLanceCode ?? "").trim() === "車線-X") current.truckX += cartonQty;

        current.total += cartonQty;
        summaryMap.set(dayKey, current);
      });

      return Array.from(summaryMap.values()).sort((a, b) => a.date.localeCompare(b.date));
    },
    [],
  );

  const calcSummary = useCallback((dailyRows: DailySummaryRow[]) => {
    return dailyRows.reduce(
      (acc, row) => {
        acc.floor2F += row.floor2F;
        acc.floor4F += row.floor4F;
        acc.truckX += row.truckX;
        acc.total += row.total;
        return acc;
      },
      { floor2F: 0, floor4F: 0, truckX: 0, total: 0 },
    );
  }, []);

  const styleWorksheet = useCallback((worksheet: XLSX.WorkSheet, dataRowsCount: number) => {
    const summaryTitleRow = 4 + dataRowsCount;
    const summaryStartRow = 5 + dataRowsCount;

    worksheet["!cols"] = [{ wch: 16 }, { wch: 14 }, { wch: 14 }, { wch: 16 }, { wch: 14 }];
    worksheet["!merges"] = [
      { s: { r: 0, c: 0 }, e: { r: 0, c: 4 } },
      { s: { r: summaryTitleRow, c: 0 }, e: { r: summaryTitleRow, c: 4 } },
    ];

    const titleStyle = {
      font: { bold: true, sz: 14, color: { rgb: "1F2D3D" } },
      alignment: { horizontal: "center", vertical: "center" },
      fill: { fgColor: { rgb: "EAF3FF" } },
    };
    const headerStyle = {
      font: { bold: true, color: { rgb: "FFFFFF" } },
      fill: { fgColor: { rgb: "1976D2" } },
      alignment: { horizontal: "center", vertical: "center" },
      border: {
        top: { style: "thin", color: { rgb: "B0BEC5" } },
        bottom: { style: "thin", color: { rgb: "B0BEC5" } },
        left: { style: "thin", color: { rgb: "B0BEC5" } },
        right: { style: "thin", color: { rgb: "B0BEC5" } },
      },
    };
    const cellStyle = {
      alignment: { vertical: "center" },
      border: {
        top: { style: "thin", color: { rgb: "D0D7DE" } },
        bottom: { style: "thin", color: { rgb: "D0D7DE" } },
        left: { style: "thin", color: { rgb: "D0D7DE" } },
        right: { style: "thin", color: { rgb: "D0D7DE" } },
      },
    };
    const numberStyle = {
      ...cellStyle,
      alignment: { horizontal: "right", vertical: "center" },
      numFmt: "#,##0",
    };
    const summaryTitleStyle = {
      font: { bold: true, color: { rgb: "1F2D3D" } },
      fill: { fgColor: { rgb: "F1F8E9" } },
      alignment: { horizontal: "left", vertical: "center" },
    };

    for (let c = 0; c <= 4; c += 1) {
      const headerCell = XLSX.utils.encode_cell({ r: 2, c });
      if (worksheet[headerCell]) worksheet[headerCell].s = headerStyle;
    }

    for (let r = 3; r < 3 + dataRowsCount; r += 1) {
      for (let c = 0; c <= 4; c += 1) {
        const addr = XLSX.utils.encode_cell({ r, c });
        if (!worksheet[addr]) continue;
        worksheet[addr].s = c === 0 ? cellStyle : numberStyle;
      }
    }

    for (let r = summaryStartRow; r <= summaryStartRow + 3; r += 1) {
      const labelAddr = XLSX.utils.encode_cell({ r, c: 0 });
      const valueAddr = XLSX.utils.encode_cell({ r, c: 1 });
      if (worksheet[labelAddr]) worksheet[labelAddr].s = cellStyle;
      if (worksheet[valueAddr]) worksheet[valueAddr].s = numberStyle;
    }

    if (worksheet["A1"]) worksheet["A1"].s = titleStyle;
    const summaryTitleAddr = XLSX.utils.encode_cell({ r: summaryTitleRow, c: 0 });
    if (worksheet[summaryTitleAddr]) worksheet[summaryTitleAddr].s = summaryTitleStyle;
  }, []);

  const addReportSheet = useCallback(
    (
      workbook: XLSX.WorkBook,
      sheetName: string,
      reportTitle: string,
      dailyRows: DailySummaryRow[],
    ) => {
      const reportSummary = calcSummary(dailyRows);
      const aoa: (string | number)[][] = [
        [reportTitle, "", "", "", ""],
        ["", "", "", "", ""],
        ["日期", "2/F 出箱數", "4/F 出箱數", "車線-X 出箱數", "總出箱數"],
        ...dailyRows.map((row) => [row.date, row.floor2F, row.floor4F, row.truckX, row.total]),
        ["", "", "", "", ""],
        ["彙總", "", "", "", ""],
        ["2/F 出箱數", reportSummary.floor2F, "", "", ""],
        ["4/F 出箱數", reportSummary.floor4F, "", "", ""],
        ["車線-X 出箱數", reportSummary.truckX, "", "", ""],
        ["總出箱數", reportSummary.total, "", "", ""],
      ];

      const worksheet = XLSX.utils.aoa_to_sheet(aoa);
      styleWorksheet(worksheet, dailyRows.length);
      XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
    },
    [calcSummary, styleWorksheet],
  );

  const handleDownloadExcel = useCallback(async () => {
    setIsExporting(true);
    try {
      const allRecords =
        mode === "workbench"
          ? await fetchCompletedDoPickOrdersWorkbenchAll()
          : await fetchCompletedDoPickOrdersAll();

      const baseDate = dayjs(date || undefined).isValid() ? dayjs(date) : dayjs();
      const floorLabel = floor === "all" ? "全部樓層" : floor;
      const dateLabel = baseDate.format("YYYY-MM-DD");

      const last7Rows = buildDailyRowsFromRecords(
        allRecords,
        baseDate.subtract(6, "day"),
        baseDate,
        floor,
      );
      const monthRows = buildDailyRowsFromRecords(
        allRecords,
        baseDate.startOf("month"),
        baseDate.endOf("month"),
        floor,
      );
      const yearRows = buildDailyRowsFromRecords(
        allRecords,
        baseDate.startOf("year"),
        baseDate.endOf("year"),
        floor,
      );

      const workbook = XLSX.utils.book_new();
      addReportSheet(
        workbook,
        "最近7天",
        `成品出倉出箱數量（最近7天）- ${floorLabel} - 基準日 ${dateLabel}`,
        last7Rows,
      );
      addReportSheet(
        workbook,
        "本月",
        `成品出倉出箱數量（本月）- ${floorLabel} - ${baseDate.format("YYYY年MM月")}`,
        monthRows,
      );
      addReportSheet(
        workbook,
        "本年",
        `成品出倉出箱數量（本年）- ${floorLabel} - ${baseDate.format("YYYY年")}`,
        yearRows,
      );

      XLSX.writeFile(workbook, `成品出倉出箱數量_多時段報表_${floorLabel.replace("/", "")}_${dateLabel}.xlsx`);
    } finally {
      setIsExporting(false);
    }
  }, [mode, date, floor, buildDailyRowsFromRecords, addReportSheet]);

  return (
    <Box sx={{ width: "100%" }}>
      <Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ mb: 2 }}>
        <Typography variant="h6">成品出倉出箱數量</Typography>
        <Button
          variant="contained"
          onClick={handleDownloadExcel}
          disabled={loading || isExporting}
        >
          {isExporting ? "匯出中..." : "下載 Excel"}
        </Button>
      </Stack>

      {error && (
        <Alert severity="error" sx={{ mb: 2 }}>
          {error}
        </Alert>
      )}

      {loading ? (
        <Box sx={{ py: 6, display: "flex", justifyContent: "center" }}>
          <CircularProgress />
        </Box>
      ) : (
        <Stack spacing={2}>
          <Grid container spacing={1.5}>
            <Grid item xs={12} md={6}>
              <TextField
                select
                fullWidth
                label="樓層"
                value={floor}
                onChange={(event) => setFloor(event.target.value as FloorFilter)}
              >
                <MenuItem value="all">全部</MenuItem>
                <MenuItem value="2/F">2/F</MenuItem>
                <MenuItem value="4/F">4/F</MenuItem>
              </TextField>
            </Grid>
            <Grid item xs={12} md={6}>
              <TextField
                fullWidth
                label="日期"
                type="date"
                value={date}
                InputLabelProps={{ shrink: true }}
                onChange={(event) => setDate(event.target.value)}
              />
            </Grid>
          </Grid>

          <Grid container spacing={1.5} alignItems="stretch">
            <Grid item xs={12} md={4}>
              <TableContainer component={Paper} sx={{ height: "100%" }}>
                <Table size="small">
                  <TableBody>
                    <TableRow>
                      <TableCell>2/F 出箱數</TableCell>
                      <TableCell align="right">{summary.floor2F.toLocaleString("zh-HK")}</TableCell>
                    </TableRow>
                    <TableRow>
                      <TableCell>4/F 出箱數</TableCell>
                      <TableCell align="right">{summary.floor4F.toLocaleString("zh-HK")}</TableCell>
                    </TableRow>
                    <TableRow>
                      <TableCell>車線-X 出箱數</TableCell>
                      <TableCell align="right">{summary.truckX.toLocaleString("zh-HK")}</TableCell>
                    </TableRow>
                    <TableRow>
                      <TableCell>總出箱數</TableCell>
                      <TableCell align="right">{summary.total.toLocaleString("zh-HK")}</TableCell>
                    </TableRow>
                  </TableBody>
                </Table>
              </TableContainer>
            </Grid>
            <Grid item xs={12} md={8}>
              <Paper sx={{ p: 1.5, height: "100%" }}>
                <SafeApexCharts
                  type="bar"
                  height={240}
                  options={chartOptions}
                  series={chartSeries}
                  chartRevision={`${floor}-${date}-${rows.length}`}
                />
              </Paper>
            </Grid>
          </Grid>
        </Stack>
      )}
    </Box>
  );
};

export default FinishedGoodCartonDashboardTab;
