"use client";

import React, { useCallback, useState } from "react";
import { Box, Typography, Skeleton, Alert, TextField, Button, Stack } from "@mui/material";
import Link from "next/link";
import dayjs from "dayjs";
import Assignment from "@mui/icons-material/Assignment";
import Microwave from "@mui/icons-material/Microwave";
import {
  fetchJobOrderByStatus,
  fetchJobOrderCountByDate,
  fetchJobOrderCreatedCompletedByDate,
  fetchJobMaterialPendingPickedByDate,
  fetchJobProcessPendingCompletedByDate,
  fetchJobEquipmentWorkingWorkedByDate,
} from "@/app/api/chart/client";
import ChartCard from "../_components/ChartCard";
import DateRangeSelect from "../_components/DateRangeSelect";
import { toDateRange, DEFAULT_RANGE_DAYS } from "../_components/constants";
import SafeApexCharts from "@/components/charts/SafeApexCharts";

const PAGE_TITLE = "工單";

type Criteria = {
  joCountByDate: { rangeDays: number };
  joCreatedCompleted: { rangeDays: number };
  joDetail: { rangeDays: number };
};

const defaultCriteria: Criteria = {
  joCountByDate: { rangeDays: DEFAULT_RANGE_DAYS },
  joCreatedCompleted: { rangeDays: DEFAULT_RANGE_DAYS },
  joDetail: { rangeDays: DEFAULT_RANGE_DAYS },
};

export default function JobOrderChartPage() {
  const [joTargetDate, setJoTargetDate] = useState<string>(() => dayjs().format("YYYY-MM-DD"));
  const [criteria, setCriteria] = useState<Criteria>(defaultCriteria);
  const [error, setError] = useState<string | null>(null);
  const [chartData, setChartData] = useState<{
    joStatus: { status: string; count: number }[];
    joCountByDate: { date: string; orderCount: number }[];
    joCreatedCompleted: { date: string; createdCount: number; completedCount: number }[];
    joMaterial: { date: string; pendingCount: number; pickedCount: number }[];
    joProcess: { date: string; pendingCount: number; completedCount: number }[];
    joEquipment: { date: string; workingCount: number; workedCount: number }[];
  }>({
    joStatus: [],
    joCountByDate: [],
    joCreatedCompleted: [],
    joMaterial: [],
    joProcess: [],
    joEquipment: [],
  });
  const [loadingCharts, setLoadingCharts] = useState<Record<string, boolean>>({});

  const updateCriteria = useCallback(
    <K extends keyof Criteria>(key: K, updater: (prev: Criteria[K]) => Criteria[K]) => {
      setCriteria((prev) => ({ ...prev, [key]: updater(prev[key]) }));
    },
    []
  );
  const setChartLoading = useCallback((key: string, value: boolean) => {
    setLoadingCharts((prev) => (prev[key] === value ? prev : { ...prev, [key]: value }));
  }, []);

  React.useEffect(() => {
    setChartLoading("joStatus", true);
    fetchJobOrderByStatus(joTargetDate)
      .then((data) =>
        setChartData((prev) => ({
          ...prev,
          joStatus: data as { status: string; count: number }[],
        }))
      )
      .catch((err) => setError(err instanceof Error ? err.message : "Request failed"))
      .finally(() => setChartLoading("joStatus", false));
  }, [joTargetDate, setChartLoading]);

  React.useEffect(() => {
    const { startDate: s, endDate: e } = toDateRange(criteria.joCountByDate.rangeDays);
    setChartLoading("joCountByDate", true);
    fetchJobOrderCountByDate(s, e)
      .then((data) =>
        setChartData((prev) => ({
          ...prev,
          joCountByDate: data as { date: string; orderCount: number }[],
        }))
      )
      .catch((err) => setError(err instanceof Error ? err.message : "Request failed"))
      .finally(() => setChartLoading("joCountByDate", false));
  }, [criteria.joCountByDate, setChartLoading]);

  React.useEffect(() => {
    const { startDate: s, endDate: e } = toDateRange(criteria.joCreatedCompleted.rangeDays);
    setChartLoading("joCreatedCompleted", true);
    fetchJobOrderCreatedCompletedByDate(s, e)
      .then((data) =>
        setChartData((prev) => ({
          ...prev,
          joCreatedCompleted: data as {
            date: string;
            createdCount: number;
            completedCount: number;
          }[],
        }))
      )
      .catch((err) => setError(err instanceof Error ? err.message : "Request failed"))
      .finally(() => setChartLoading("joCreatedCompleted", false));
  }, [criteria.joCreatedCompleted, setChartLoading]);

  React.useEffect(() => {
    const { startDate: s, endDate: e } = toDateRange(criteria.joDetail.rangeDays);
    setChartLoading("joMaterial", true);
    fetchJobMaterialPendingPickedByDate(s, e)
      .then((data) =>
        setChartData((prev) => ({
          ...prev,
          joMaterial: data as { date: string; pendingCount: number; pickedCount: number }[],
        }))
      )
      .catch((err) => setError(err instanceof Error ? err.message : "Request failed"))
      .finally(() => setChartLoading("joMaterial", false));
  }, [criteria.joDetail, setChartLoading]);

  React.useEffect(() => {
    const { startDate: s, endDate: e } = toDateRange(criteria.joDetail.rangeDays);
    setChartLoading("joProcess", true);
    fetchJobProcessPendingCompletedByDate(s, e)
      .then((data) =>
        setChartData((prev) => ({
          ...prev,
          joProcess: data as { date: string; pendingCount: number; completedCount: number }[],
        }))
      )
      .catch((err) => setError(err instanceof Error ? err.message : "Request failed"))
      .finally(() => setChartLoading("joProcess", false));
  }, [criteria.joDetail, setChartLoading]);

  React.useEffect(() => {
    const { startDate: s, endDate: e } = toDateRange(criteria.joDetail.rangeDays);
    setChartLoading("joEquipment", true);
    fetchJobEquipmentWorkingWorkedByDate(s, e)
      .then((data) =>
        setChartData((prev) => ({
          ...prev,
          joEquipment: data as { date: string; workingCount: number; workedCount: number }[],
        }))
      )
      .catch((err) => setError(err instanceof Error ? err.message : "Request failed"))
      .finally(() => setChartLoading("joEquipment", false));
  }, [criteria.joDetail, setChartLoading]);

  return (
    <Box sx={{ maxWidth: 1200, mx: "auto" }}>
      <Stack direction="row" alignItems="center" justifyContent="space-between" flexWrap="wrap" gap={1} sx={{ mb: 2 }}>
        <Typography variant="h5" sx={{ fontWeight: 600, display: "flex", alignItems: "center", gap: 1 }}>
          <Assignment /> {PAGE_TITLE}
        </Typography>
        <Stack direction="row" spacing={1} flexWrap="wrap" useFlexGap>
          <Button component={Link} href="/chart/joborder/board" variant="outlined" size="small">
            工單即時看板
          </Button>
          <Button
            component={Link}
            href="/chart/equipment/board"
            variant="outlined"
            size="small"
            startIcon={<Microwave />}
          >
            設備使用看板
          </Button>
          <Button component={Link} href="/chart/process/board" variant="outlined" size="small">
            工序即時看板
          </Button>
        </Stack>
      </Stack>
      {error && (
        <Alert severity="error" sx={{ mb: 2 }} onClose={() => setError(null)}>
          {error}
        </Alert>
      )}

      <ChartCard
        title="工單按狀態"
        exportFilename="工單_按狀態"
        exportData={chartData.joStatus.map((p) => ({ 狀態: p.status, 數量: p.count }))}
        filters={
          <TextField
            size="small"
            label="日期（計劃開始）"
            type="date"
            value={joTargetDate}
            onChange={(e) => setJoTargetDate(e.target.value)}
            InputLabelProps={{ shrink: true }}
            sx={{ minWidth: 180 }}
          />
        }
      >
        {loadingCharts.joStatus ? (
          <Skeleton variant="rectangular" height={320} />
        ) : (
          <SafeApexCharts
            options={{
              chart: { type: "donut" },
              labels: chartData.joStatus.map((p) => p.status),
              legend: { position: "bottom" },
            }}
            series={chartData.joStatus.map((p) => p.count)}
            type="donut"
            width="100%"
            height={320}
          />
        )}
      </ChartCard>

      <ChartCard
        title="按日期工單數量（計劃開始日）"
        exportFilename="工單數量_按日期"
        exportData={chartData.joCountByDate.map((d) => ({ 日期: d.date, 工單數: d.orderCount }))}
        filters={
          <DateRangeSelect
            value={criteria.joCountByDate.rangeDays}
            onChange={(v) => updateCriteria("joCountByDate", (c) => ({ ...c, rangeDays: v }))}
          />
        }
      >
        {loadingCharts.joCountByDate ? (
          <Skeleton variant="rectangular" height={320} />
        ) : (
          <SafeApexCharts
            options={{
              chart: { type: "bar" },
              xaxis: { categories: chartData.joCountByDate.map((d) => d.date) },
              yaxis: { title: { text: "單數" } },
              plotOptions: { bar: { columnWidth: "60%" } },
              dataLabels: { enabled: false },
            }}
            series={[{ name: "工單數", data: chartData.joCountByDate.map((d) => d.orderCount) }]}
            type="bar"
            width="100%"
            height={320}
          />
        )}
      </ChartCard>

      <ChartCard
        title="工單創建與完成按日期"
        exportFilename="工單創建與完成_按日期"
        exportData={chartData.joCreatedCompleted.map((d) => ({ 日期: d.date, 創建: d.createdCount, 完成: d.completedCount }))}
        filters={
          <DateRangeSelect
            value={criteria.joCreatedCompleted.rangeDays}
            onChange={(v) => updateCriteria("joCreatedCompleted", (c) => ({ ...c, rangeDays: v }))}
          />
        }
      >
        {loadingCharts.joCreatedCompleted ? (
          <Skeleton variant="rectangular" height={320} />
        ) : (
          <SafeApexCharts
            options={{
              chart: { type: "line" },
              xaxis: { categories: chartData.joCreatedCompleted.map((d) => d.date) },
              yaxis: { title: { text: "數量" } },
              stroke: { curve: "smooth" },
              dataLabels: { enabled: false },
            }}
            series={[
              { name: "創建", data: chartData.joCreatedCompleted.map((d) => d.createdCount) },
              { name: "完成", data: chartData.joCreatedCompleted.map((d) => d.completedCount) },
            ]}
            type="line"
            width="100%"
            height={320}
          />
        )}
      </ChartCard>

      <Typography variant="h6" sx={{ mt: 3, mb: 1, fontWeight: 600 }}>
        工單物料／工序／設備
      </Typography>
      <ChartCard
        title="物料待領／已揀（按工單計劃日）"
        exportFilename="工單物料_待領已揀_按日期"
        exportData={chartData.joMaterial.map((d) => ({ 日期: d.date, 待領: d.pendingCount, 已揀: d.pickedCount }))}
        filters={
          <DateRangeSelect
            value={criteria.joDetail.rangeDays}
            onChange={(v) => updateCriteria("joDetail", (c) => ({ ...c, rangeDays: v }))}
          />
        }
      >
        {loadingCharts.joMaterial ? (
          <Skeleton variant="rectangular" height={320} />
        ) : (
          <SafeApexCharts
            options={{
              chart: { type: "bar" },
              xaxis: { categories: chartData.joMaterial.map((d) => d.date) },
              yaxis: { title: { text: "筆數" } },
              plotOptions: { bar: { columnWidth: "60%" } },
              dataLabels: { enabled: false },
              legend: { position: "top" },
            }}
            series={[
              { name: "待領", data: chartData.joMaterial.map((d) => d.pendingCount) },
              { name: "已揀", data: chartData.joMaterial.map((d) => d.pickedCount) },
            ]}
            type="bar"
            width="100%"
            height={320}
          />
        )}
      </ChartCard>

      <ChartCard
        title="工序待完成／已完成（按工單計劃日）"
        exportFilename="工單工序_待完成已完成_按日期"
        exportData={chartData.joProcess.map((d) => ({ 日期: d.date, 待完成: d.pendingCount, 已完成: d.completedCount }))}
        filters={
          <DateRangeSelect
            value={criteria.joDetail.rangeDays}
            onChange={(v) => updateCriteria("joDetail", (c) => ({ ...c, rangeDays: v }))}
          />
        }
      >
        {loadingCharts.joProcess ? (
          <Skeleton variant="rectangular" height={320} />
        ) : (
          <SafeApexCharts
            options={{
              chart: { type: "bar" },
              xaxis: { categories: chartData.joProcess.map((d) => d.date) },
              yaxis: { title: { text: "筆數" } },
              plotOptions: { bar: { columnWidth: "60%" } },
              dataLabels: { enabled: false },
              legend: { position: "top" },
            }}
            series={[
              { name: "待完成", data: chartData.joProcess.map((d) => d.pendingCount) },
              { name: "已完成", data: chartData.joProcess.map((d) => d.completedCount) },
            ]}
            type="bar"
            width="100%"
            height={320}
          />
        )}
      </ChartCard>

      <ChartCard
        title="設備使用中／已使用（按工單）"
        exportFilename="工單設備_使用中已使用_按日期"
        exportData={chartData.joEquipment.map((d) => ({ 日期: d.date, 使用中: d.workingCount, 已使用: d.workedCount }))}
        filters={
          <DateRangeSelect
            value={criteria.joDetail.rangeDays}
            onChange={(v) => updateCriteria("joDetail", (c) => ({ ...c, rangeDays: v }))}
          />
        }
      >
        {loadingCharts.joEquipment ? (
          <Skeleton variant="rectangular" height={320} />
        ) : (
          <SafeApexCharts
            options={{
              chart: { type: "bar" },
              xaxis: { categories: chartData.joEquipment.map((d) => d.date) },
              yaxis: { title: { text: "筆數" } },
              plotOptions: { bar: { columnWidth: "60%" } },
              dataLabels: { enabled: false },
              legend: { position: "top" },
            }}
            series={[
              { name: "使用中", data: chartData.joEquipment.map((d) => d.workingCount) },
              { name: "已使用", data: chartData.joEquipment.map((d) => d.workedCount) },
            ]}
            type="bar"
            width="100%"
            height={320}
          />
        )}
      </ChartCard>
    </Box>
  );
}
