"use client";

import React, { useState } from "react";
import {
  Box,
  Typography,
  Skeleton,
  Alert,
  TextField,
  CircularProgress,
  Button,
  Stack,
  Grid,
  Autocomplete,
  Chip,
  Paper,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
} from "@mui/material";
import dynamic from "next/dynamic";
import ShoppingCart from "@mui/icons-material/ShoppingCart";
import TableChart from "@mui/icons-material/TableChart";
import {
  fetchPurchaseOrderByStatus,
  fetchPurchaseOrderDetailsByStatus,
  fetchPurchaseOrderItems,
  fetchPurchaseOrderItemsByStatus,
  fetchPurchaseOrderFilterOptions,
  fetchPurchaseOrderEstimatedArrivalSummary,
  fetchPurchaseOrderEstimatedArrivalBreakdown,
  PurchaseOrderDetailByStatusRow,
  PurchaseOrderItemRow,
  PurchaseOrderChartFilters,
  PurchaseOrderFilterOptions,
  PurchaseOrderEstimatedArrivalRow,
  PurchaseOrderDrillQuery,
  PurchaseOrderEstimatedArrivalBreakdown,
} from "@/app/api/chart/client";
import ChartCard from "../_components/ChartCard";
import { exportPurchaseChartMasterToFile } from "./exportPurchaseChartMaster";
import dayjs from "dayjs";

const ApexCharts = dynamic(() => import("react-apexcharts"), { ssr: false });

const PAGE_TITLE = "採購";
const DEFAULT_DRILL_STATUS = "completed";
/** Must match backend `getPurchaseOrderByStatus` (orderDate). Using "complete" here desyncs drill-down from the donut counts. */
const DRILL_DATE_FILTER = "order" as const;

const EST_BUCKETS = ["delivered", "not_delivered", "cancelled", "other"] as const;

/** 預計送貨 — 已送 / 未送 / 已取消 / 其他 */
const ESTIMATE_DONUT_COLORS = ["#2e7d32", "#f57c00", "#78909c", "#7b1fa2"];

/** 實際已送貨（依狀態）— 依序上色 */
const STATUS_DONUT_COLORS = ["#1565c0", "#00838f", "#6a1b9a", "#c62828", "#5d4037", "#00695c"];

/** ApexCharts + React: avoid updating state inside dataPointSelection synchronously (DOM getAttribute null). */
function deferChartClick(fn: () => void) {
  window.setTimeout(fn, 0);
}

/** UI labels only; API still uses English status values. */
function poStatusLabelZh(status: string): string {
  const s = status.trim().toLowerCase();
  switch (s) {
    case "pending":
      return "待處理";
    case "completed":
      return "已完成";
    case "receiving":
      return "收貨中";
    default:
      return status;
  }
}

function bucketLabelZh(bucket: string): string {
  switch (bucket) {
    case "delivered":
      return "已送";
    case "not_delivered":
      return "未送";
    case "cancelled":
      return "已取消";
    case "other":
      return "其他";
    default:
      return bucket;
  }
}

function emptyFilterOptions(): PurchaseOrderFilterOptions {
  return { suppliers: [], items: [], poNos: [] };
}

export default function PurchaseChartPage() {
  const [poTargetDate, setPoTargetDate] = useState<string>(() => dayjs().format("YYYY-MM-DD"));
  const [error, setError] = useState<string | null>(null);
  const [chartData, setChartData] = useState<{ status: string; count: number }[]>([]);
  const [estimatedArrivalData, setEstimatedArrivalData] = useState<PurchaseOrderEstimatedArrivalRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [estimatedLoading, setEstimatedLoading] = useState(true);
  const [filterOptions, setFilterOptions] = useState<PurchaseOrderFilterOptions>(emptyFilterOptions);
  const [filterOptionsLoading, setFilterOptionsLoading] = useState(false);

  const [filterSupplierIds, setFilterSupplierIds] = useState<number[]>([]);
  const [filterItemCodes, setFilterItemCodes] = useState<string[]>([]);
  const [filterPoNos, setFilterPoNos] = useState<string[]>([]);

  const [selectedStatus, setSelectedStatus] = useState<string | null>(null);
  /** Prefer id (shop row); code-only used when supplierId missing */
  const [selectedSupplierId, setSelectedSupplierId] = useState<number | null>(null);
  const [selectedSupplierCode, setSelectedSupplierCode] = useState<string | null>(null);
  const [selectedItemCode, setSelectedItemCode] = useState<string | null>(null);
  /** 預計送貨 donut — filters lower charts via API */
  const [selectedEstimatedBucket, setSelectedEstimatedBucket] = useState<string | null>(null);
  const [poDetails, setPoDetails] = useState<PurchaseOrderDetailByStatusRow[]>([]);
  const [poDetailsLoading, setPoDetailsLoading] = useState(false);
  const [selectedPo, setSelectedPo] = useState<PurchaseOrderDetailByStatusRow | null>(null);
  const [itemsSummary, setItemsSummary] = useState<PurchaseOrderItemRow[]>([]);
  const [itemsSummaryLoading, setItemsSummaryLoading] = useState(false);
  const [poLineItems, setPoLineItems] = useState<PurchaseOrderItemRow[]>([]);
  const [poLineItemsLoading, setPoLineItemsLoading] = useState(false);
  const [masterExportLoading, setMasterExportLoading] = useState(false);
  const [eaBreakdown, setEaBreakdown] = useState<PurchaseOrderEstimatedArrivalBreakdown | null>(null);
  const [eaBreakdownLoading, setEaBreakdownLoading] = useState(false);

  const effectiveStatus = selectedStatus ?? DEFAULT_DRILL_STATUS;

  /** Top charts (實際已送貨 + 預計送貨): date + multi-select only — no drill-down from lower charts. */
  const barFilters = React.useMemo((): PurchaseOrderChartFilters => {
    return {
      supplierIds: filterSupplierIds.length ? filterSupplierIds : undefined,
      itemCodes: filterItemCodes.length ? filterItemCodes : undefined,
      purchaseOrderNos: filterPoNos.length ? filterPoNos : undefined,
    };
  }, [filterSupplierIds, filterItemCodes, filterPoNos]);

  /** Drill-down: bar filters ∩ supplier/貨品 chart selection. */
  const drillFilters = React.useMemo((): PurchaseOrderChartFilters | null => {
    if (
      selectedSupplierId != null &&
      selectedSupplierId > 0 &&
      filterSupplierIds.length > 0 &&
      !filterSupplierIds.includes(selectedSupplierId)
    ) {
      return null;
    }
    if (
      selectedItemCode?.trim() &&
      filterItemCodes.length > 0 &&
      !filterItemCodes.includes(selectedItemCode.trim())
    ) {
      return null;
    }
    if (selectedSupplierCode?.trim() && filterSupplierIds.length > 0) {
      const opt = filterOptions.suppliers.find((s) => s.code === selectedSupplierCode.trim());
      if (!opt || opt.supplierId <= 0 || !filterSupplierIds.includes(opt.supplierId)) {
        return null;
      }
    }

    const out: PurchaseOrderChartFilters = {
      supplierIds: filterSupplierIds.length ? [...filterSupplierIds] : undefined,
      itemCodes: filterItemCodes.length ? [...filterItemCodes] : undefined,
      purchaseOrderNos: filterPoNos.length ? [...filterPoNos] : undefined,
    };

    if (selectedSupplierId != null && selectedSupplierId > 0) {
      if (!out.supplierIds?.length) {
        out.supplierIds = [selectedSupplierId];
      } else if (out.supplierIds.includes(selectedSupplierId)) {
        out.supplierIds = [selectedSupplierId];
      }
      out.supplierCode = undefined;
    } else if (selectedSupplierCode?.trim()) {
      const code = selectedSupplierCode.trim();
      const opt = filterOptions.suppliers.find((s) => s.code === code);
      if (out.supplierIds?.length) {
        if (opt && opt.supplierId > 0 && out.supplierIds.includes(opt.supplierId)) {
          out.supplierIds = [opt.supplierId];
        } else {
          return null;
        }
      } else {
        out.supplierIds = undefined;
        out.supplierCode = code;
      }
    }

    if (selectedItemCode?.trim()) {
      const ic = selectedItemCode.trim();
      if (!out.itemCodes?.length) {
        out.itemCodes = [ic];
      } else if (out.itemCodes.includes(ic)) {
        out.itemCodes = [ic];
      }
    }

    return out;
  }, [
    filterSupplierIds,
    filterItemCodes,
    filterPoNos,
    selectedSupplierId,
    selectedSupplierCode,
    selectedItemCode,
    filterOptions.suppliers,
  ]);

  const drillQueryOpts = React.useMemo((): PurchaseOrderDrillQuery | null => {
    if (drillFilters === null) return null;
    return {
      ...drillFilters,
      estimatedArrivalBucket: selectedEstimatedBucket ?? undefined,
    };
  }, [drillFilters, selectedEstimatedBucket]);

  React.useEffect(() => {
    setFilterOptionsLoading(true);
    fetchPurchaseOrderFilterOptions(poTargetDate)
      .then(setFilterOptions)
      .catch((err) => setError(err instanceof Error ? err.message : "Request failed"))
      .finally(() => setFilterOptionsLoading(false));
  }, [poTargetDate]);

  React.useEffect(() => {
    setLoading(true);
    fetchPurchaseOrderByStatus(poTargetDate, barFilters)
      .then((data) => setChartData(data as { status: string; count: number }[]))
      .catch((err) => setError(err instanceof Error ? err.message : "Request failed"))
      .finally(() => setLoading(false));
  }, [poTargetDate, barFilters]);

  React.useEffect(() => {
    setEstimatedLoading(true);
    fetchPurchaseOrderEstimatedArrivalSummary(poTargetDate, barFilters)
      .then(setEstimatedArrivalData)
      .catch((err) => setError(err instanceof Error ? err.message : "Request failed"))
      .finally(() => setEstimatedLoading(false));
  }, [poTargetDate, barFilters]);

  React.useEffect(() => {
    if (!selectedEstimatedBucket || !poTargetDate) {
      setEaBreakdown(null);
      return;
    }
    setEaBreakdownLoading(true);
    fetchPurchaseOrderEstimatedArrivalBreakdown(poTargetDate, selectedEstimatedBucket, barFilters)
      .then(setEaBreakdown)
      .catch((err) => setError(err instanceof Error ? err.message : "Request failed"))
      .finally(() => setEaBreakdownLoading(false));
  }, [selectedEstimatedBucket, poTargetDate, barFilters]);

  React.useEffect(() => {
    if (drillQueryOpts === null) {
      setPoDetails([]);
      return;
    }
    setPoDetailsLoading(true);
    fetchPurchaseOrderDetailsByStatus(effectiveStatus, poTargetDate, {
      dateFilter: DRILL_DATE_FILTER,
      ...drillQueryOpts,
    })
      .then((rows) => setPoDetails(rows))
      .catch((err) => setError(err instanceof Error ? err.message : "Request failed"))
      .finally(() => setPoDetailsLoading(false));
  }, [effectiveStatus, poTargetDate, drillQueryOpts]);

  React.useEffect(() => {
    if (selectedPo) return;
    if (drillQueryOpts === null) {
      setItemsSummary([]);
      return;
    }
    setItemsSummaryLoading(true);
    fetchPurchaseOrderItemsByStatus(effectiveStatus, poTargetDate, {
      dateFilter: DRILL_DATE_FILTER,
      ...drillQueryOpts,
    })
      .then((rows) => setItemsSummary(rows))
      .catch((err) => setError(err instanceof Error ? err.message : "Request failed"))
      .finally(() => setItemsSummaryLoading(false));
  }, [selectedPo, effectiveStatus, poTargetDate, drillQueryOpts]);

  React.useEffect(() => {
    if (selectedPo) return;
    setPoLineItems([]);
    setPoLineItemsLoading(false);
  }, [selectedPo]);

  const handleStatusClick = (status: string) => {
    const normalized = status.trim().toLowerCase();
    setSelectedStatus((prev) => (prev === normalized ? null : normalized));
    /** 與「預計送貨」圓環互斥：只顯示一則上方圓環篩選說明 */
    setSelectedEstimatedBucket(null);
    setSelectedPo(null);
    setSelectedSupplierId(null);
    setSelectedSupplierCode(null);
    setSelectedItemCode(null);
    setPoLineItems([]);
  };

  const handleEstimatedBucketClick = (index: number) => {
    const bucket = EST_BUCKETS[index];
    if (!bucket) return;
    setSelectedEstimatedBucket((prev) => (prev === bucket ? null : bucket));
    /** 與「實際已送貨」圓環互斥：只顯示一則上方圓環篩選說明 */
    setSelectedStatus(null);
    setSelectedPo(null);
    setPoLineItems([]);
  };

  const handleClearFilters = () => {
    setFilterSupplierIds([]);
    setFilterItemCodes([]);
    setFilterPoNos([]);
    setSelectedSupplierId(null);
    setSelectedSupplierCode(null);
    setSelectedItemCode(null);
    setSelectedEstimatedBucket(null);
    setSelectedStatus(null);
    setSelectedPo(null);
    setPoLineItems([]);
  };

  const handleItemSummaryClick = (index: number) => {
    const row = itemsSummary[index];
    if (!row?.itemCode) return;
    setSelectedItemCode((prev) => (prev === row.itemCode ? null : row.itemCode));
    setSelectedPo(null);
    setPoLineItems([]);
  };

  const handleSupplierClick = (row: {
    supplierId: number | null;
    supplierCode: string;
  }) => {
    if (row.supplierId != null && row.supplierId > 0) {
      setSelectedSupplierId((prev) => (prev === row.supplierId ? null : row.supplierId));
      setSelectedSupplierCode(null);
    } else if (row.supplierCode.trim()) {
      setSelectedSupplierCode((prev) => (prev === row.supplierCode ? null : row.supplierCode));
      setSelectedSupplierId(null);
    }
    setSelectedPo(null);
    setPoLineItems([]);
  };

  const handlePoClick = async (row: PurchaseOrderDetailByStatusRow) => {
    setSelectedPo(row);
    setPoLineItems([]);
    setPoLineItemsLoading(true);
    try {
      const rows = await fetchPurchaseOrderItems(row.purchaseOrderId);
      setPoLineItems(rows);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Request failed");
    } finally {
      setPoLineItemsLoading(false);
    }
  };

  const supplierChartData = React.useMemo(() => {
    const map = new Map<
      string,
      {
        supplier: string;
        supplierId: number | null;
        supplierCode: string;
        count: number;
        totalQty: number;
      }
    >();
    poDetails.forEach((row) => {
      const sid = row.supplierId != null && row.supplierId > 0 ? row.supplierId : null;
      const code = String(row.supplierCode ?? "").trim();
      const name = String(row.supplierName ?? "").trim();
      const label =
        `${code} ${name}`.trim() || (sid != null ? `(Supplier #${sid})` : "(Unknown supplier)");
      const key = sid != null ? `sid:${sid}` : `code:${code}|name:${name}`;
      const curr = map.get(key) ?? {
        supplier: label,
        supplierId: sid,
        supplierCode: code,
        count: 0,
        totalQty: 0,
      };
      curr.count += 1;
      curr.totalQty += Number(row.totalQty ?? 0);
      map.set(key, curr);
    });
    return Array.from(map.values()).sort((a, b) => b.totalQty - a.totalQty);
  }, [poDetails]);

  const estimatedChartSeries = React.useMemo(() => {
    const m = new Map(estimatedArrivalData.map((r) => [r.bucket, r.count]));
    return EST_BUCKETS.map((b) => m.get(b) ?? 0);
  }, [estimatedArrivalData]);

  const handleExportPurchaseMaster = React.useCallback(async () => {
    setMasterExportLoading(true);
    try {
      const exportedAtIso = new Date().toISOString();
      const filterSupplierText =
        filterOptions.suppliers
          .filter((s) => filterSupplierIds.includes(s.supplierId))
          .map((s) => `${s.code} ${s.name}`.trim())
          .join("；") || "（未選）";
      const filterItemText =
        filterOptions.items
          .filter((i) => filterItemCodes.includes(i.itemCode))
          .map((i) => `${i.itemCode} ${i.itemName}`.trim())
          .join("；") || "（未選）";
      const filterPoText = filterPoNos.length ? filterPoNos.join("；") : "（未選）";

      const metaRows: Record<string, unknown>[] = [
        { 項目: "匯出時間_UTC", 值: exportedAtIso },
        { 項目: "訂單日期", 值: poTargetDate },
        { 項目: "多選_供應商", 值: filterSupplierText },
        { 項目: "多選_貨品", 值: filterItemText },
        { 項目: "多選_採購單號", 值: filterPoText },
        {
          項目: "預計送貨圓環_點選",
          值: selectedEstimatedBucket ? bucketLabelZh(selectedEstimatedBucket) : "（未選）",
        },
        {
          項目: "實際已送貨圓環_點選狀態",
          值:
            selectedStatus != null
              ? poStatusLabelZh(selectedStatus)
              : `（未選；下方圖表預設狀態 ${poStatusLabelZh(DEFAULT_DRILL_STATUS)}）`,
        },
        { 項目: "下方圖表套用狀態_英文", 值: effectiveStatus },
        { 項目: "下方圖表套用狀態_中文", 值: poStatusLabelZh(effectiveStatus) },
        {
          項目: "圓環篩選_供應商",
          值:
            selectedSupplierId != null && selectedSupplierId > 0
              ? `supplierId=${selectedSupplierId}`
              : selectedSupplierCode?.trim()
                ? `supplierCode=${selectedSupplierCode.trim()}`
                : "（未選）",
        },
        { 項目: "圓環篩選_貨品", 值: selectedItemCode?.trim() ? selectedItemCode.trim() : "（未選）" },
        {
          項目: "下方查詢是否有效",
          值: drillQueryOpts === null ? "否（篩選交集無效，下方表為空）" : "是",
        },
        {
          項目: "圖表說明",
          值:
            "預計送貨圖：預計到貨日=訂單日期。實際已送貨圖：訂單日期。貨品/供應商/採購單表：依下方查詢與預計送貨扇形。採購單行明細：匯出當前列表中每張採購單之全部行。",
        },
      ];

      const estimatedDonutRows = EST_BUCKETS.map((b, i) => ({
        類別: bucketLabelZh(b),
        bucket代碼: b,
        數量: estimatedChartSeries[i] ?? 0,
      }));

      const actualStatusDonutRows = chartData.map((p) => ({
        狀態中文: poStatusLabelZh(p.status),
        status代碼: p.status,
        數量: p.count,
      }));

      const itemSummaryRows = itemsSummary.map((i) => ({
        貨品: i.itemCode,
        名稱: i.itemName,
        訂購數量: i.orderedQty,
        已收貨: i.receivedQty,
        待收貨: i.pendingQty,
        UOM: i.uom,
      }));

      const supplierDistributionRows = supplierChartData.map((s) => ({
        供應商: s.supplier,
        供應商編號: s.supplierCode,
        supplierId: s.supplierId ?? "",
        採購單數: s.count,
        總數量: s.totalQty,
      }));

      const purchaseOrderListRows = poDetails.map((p) => ({
        採購單號: p.purchaseOrderNo,
        狀態: poStatusLabelZh(p.status),
        status代碼: p.status,
        訂單日期: p.orderDate,
        預計到貨日: p.estimatedArrivalDate,
        供應商編號: p.supplierCode,
        供應商名稱: p.supplierName,
        supplierId: p.supplierId ?? "",
        項目數: p.itemCount,
        總數量: p.totalQty,
      }));

      const purchaseOrderLineRows: Record<string, unknown>[] = [];
      if (poDetails.length > 0) {
        const lineBatches = await Promise.all(
          poDetails.map((po) =>
            fetchPurchaseOrderItems(po.purchaseOrderId).then((lines) =>
              lines.map((line) => ({
                採購單號: po.purchaseOrderNo,
                採購單ID: po.purchaseOrderId,
                狀態: poStatusLabelZh(po.status),
                訂單日期: po.orderDate,
                預計到貨日: po.estimatedArrivalDate,
                供應商編號: po.supplierCode,
                供應商名稱: po.supplierName,
                貨品: line.itemCode,
                品名: line.itemName,
                UOM: line.uom,
                訂購數量: line.orderedQty,
                已收貨: line.receivedQty,
                待收貨: line.pendingQty,
              }))
            )
          )
        );
        lineBatches.flat().forEach((row) => purchaseOrderLineRows.push(row));
      }

      exportPurchaseChartMasterToFile(
        {
          exportedAtIso,
          metaRows,
          estimatedDonutRows,
          actualStatusDonutRows,
          itemSummaryRows,
          supplierDistributionRows,
          purchaseOrderListRows,
          purchaseOrderLineRows,
        },
        `採購圖表總表_${poTargetDate}_${dayjs().format("HHmmss")}`
      );
    } catch (err) {
      setError(err instanceof Error ? err.message : "總表匯出失敗");
    } finally {
      setMasterExportLoading(false);
    }
  }, [
    poTargetDate,
    filterOptions.suppliers,
    filterOptions.items,
    filterSupplierIds,
    filterItemCodes,
    filterPoNos,
    selectedEstimatedBucket,
    selectedStatus,
    effectiveStatus,
    drillQueryOpts,
    estimatedChartSeries,
    chartData,
    itemsSummary,
    supplierChartData,
    poDetails,
    selectedSupplierId,
    selectedSupplierCode,
    selectedItemCode,
  ]);

  const itemChartKey = `${effectiveStatus}|${poTargetDate}|${DRILL_DATE_FILTER}|${JSON.stringify(drillQueryOpts)}|ea:${selectedEstimatedBucket ?? ""}|s`;
  const supplierChartKey = `${itemChartKey}|${selectedItemCode ?? ""}|sup`;
  const poChartKey = `${supplierChartKey}|po`;

  /** 下方三張圖：僅選預計送貨扇形時，資料依 bucket 不再套用「實際已送貨」單一狀態。 */
  const lowerChartsTitlePrefix = React.useMemo(() => {
    if (selectedEstimatedBucket) {
      return `預計送貨「${bucketLabelZh(selectedEstimatedBucket)}」`;
    }
    return `實際已送貨 ${poStatusLabelZh(effectiveStatus)}`;
  }, [selectedEstimatedBucket, effectiveStatus]);

  const lowerChartsDefaultStatusHint = React.useMemo(() => {
    if (selectedEstimatedBucket) return "";
    if (selectedStatus) return "";
    return `（預設狀態：${poStatusLabelZh(DEFAULT_DRILL_STATUS)}）`;
  }, [selectedEstimatedBucket, selectedStatus]);

  const filterHint = [
    selectedItemCode ? `貨品: ${selectedItemCode}` : null,
    selectedSupplierId != null && selectedSupplierId > 0
      ? `供應商 id: ${selectedSupplierId}`
      : selectedSupplierCode
        ? `供應商 code: ${selectedSupplierCode}`
        : null,
  ]
    .filter(Boolean)
    .join(" · ");

  const hasBarFilters = filterSupplierIds.length > 0 || filterItemCodes.length > 0 || filterPoNos.length > 0;
  const hasChartDrill =
    selectedStatus != null ||
    selectedItemCode ||
    selectedSupplierId != null ||
    selectedSupplierCode ||
    selectedEstimatedBucket ||
    selectedPo;

  return (
    <Box sx={{ maxWidth: 1200, mx: "auto" }}>
      <Typography variant="h5" sx={{ mb: 2, fontWeight: 600, display: "flex", alignItems: "center", gap: 1 }}>
        <ShoppingCart /> {PAGE_TITLE}
      </Typography>
      {error && (
        <Alert severity="error" sx={{ mb: 2 }} onClose={() => setError(null)}>
          {error}
        </Alert>
      )}

      <Stack direction="row" spacing={1} sx={{ mb: 2, flexWrap: "wrap", alignItems: "center" }}>
        <Typography variant="body2" color="text.secondary">
          上方「預計送貨」與「實際已送貨」依查詢日期與篩選條件；點擊圓環可篩選下方圖表（與其他條件交集）。
        </Typography>
        <Button
          size="small"
          variant="contained"
          color="primary"
          startIcon={masterExportLoading ? <CircularProgress size={16} color="inherit" /> : <TableChart />}
          disabled={masterExportLoading}
          onClick={() => void handleExportPurchaseMaster()}
        >
          匯出總表 Excel
        </Button>
        {(hasBarFilters || hasChartDrill) && (
          <Button size="small" variant="outlined" onClick={handleClearFilters}>
            清除篩選
          </Button>
        )}
      </Stack>

      <Stack direction="row" spacing={1} sx={{ mb: 2, flexWrap: "wrap", alignItems: "center" }} useFlexGap>
        <TextField
          size="small"
          label="查詢日期"
          type="date"
          value={poTargetDate}
          onChange={(e) => setPoTargetDate(e.target.value)}
          InputLabelProps={{ shrink: true }}
          sx={{ minWidth: 160 }}
        />
        <Autocomplete
          multiple
          size="small"
          sx={{ minWidth: 220, maxWidth: 360 }}
          loading={filterOptionsLoading}
          options={filterOptions.suppliers}
          getOptionLabel={(o) => `${o.code} ${o.name}`.trim() || String(o.supplierId)}
          value={filterOptions.suppliers.filter((s) => filterSupplierIds.includes(s.supplierId))}
          onChange={(_, v) => setFilterSupplierIds(v.map((x) => x.supplierId))}
          renderTags={(tagValue, getTagProps) =>
            tagValue.map((option, index) => (
              <Chip {...getTagProps({ index })} key={option.supplierId} size="small" label={option.code || option.supplierId} />
            ))
          }
          renderInput={(params) => <TextField {...params} label="供應商" placeholder="多選" />}
        />
        <Autocomplete
          multiple
          size="small"
          sx={{ minWidth: 220, maxWidth: 360 }}
          loading={filterOptionsLoading}
          options={filterOptions.items}
          getOptionLabel={(o) => `${o.itemCode} ${o.itemName}`.trim()}
          value={filterOptions.items.filter((i) => filterItemCodes.includes(i.itemCode))}
          onChange={(_, v) => setFilterItemCodes(v.map((x) => x.itemCode))}
          renderTags={(tagValue, getTagProps) =>
            tagValue.map((option, index) => (
              <Chip {...getTagProps({ index })} key={option.itemCode} size="small" label={option.itemCode} />
            ))
          }
          renderInput={(params) => <TextField {...params} label="貨品" placeholder="多選" />}
        />
        <Autocomplete
          multiple
          size="small"
          sx={{ minWidth: 200, maxWidth: 360 }}
          loading={filterOptionsLoading}
          options={filterOptions.poNos}
          getOptionLabel={(o) => o.poNo}
          value={filterOptions.poNos.filter((p) => filterPoNos.includes(p.poNo))}
          onChange={(_, v) => setFilterPoNos(v.map((x) => x.poNo))}
          renderTags={(tagValue, getTagProps) =>
            tagValue.map((option, index) => (
              <Chip {...getTagProps({ index })} key={option.poNo} size="small" label={option.poNo} />
            ))
          }
          renderInput={(params) => <TextField {...params} label="採購單號" placeholder="多選" />}
        />
      </Stack>

      <Grid container spacing={2} sx={{ mb: 1 }}>
        <Grid item xs={12} md={6}>
          <ChartCard
            title="預計送貨（依預計到貨日）"
            exportFilename="採購_預計送貨"
            exportData={EST_BUCKETS.map((b, i) => ({
              類別: bucketLabelZh(b),
              數量: estimatedChartSeries[i] ?? 0,
            }))}
          >
            {estimatedLoading ? (
              <Skeleton variant="rectangular" height={320} />
            ) : (
              <ApexCharts
                options={{
                  chart: {
                    type: "donut",
                    events: {
                      dataPointSelection: (_event: unknown, _chartContext: unknown, config: { dataPointIndex?: number }) => {
                        const idx = config?.dataPointIndex ?? -1;
                        if (idx < 0 || idx >= EST_BUCKETS.length) return;
                        deferChartClick(() => handleEstimatedBucketClick(idx));
                      },
                    },
                    animations: { enabled: false },
                  },
                  labels: EST_BUCKETS.map(bucketLabelZh),
                  colors: ESTIMATE_DONUT_COLORS,
                  legend: { position: "bottom" },
                  plotOptions: {
                    pie: {
                      donut: {
                        labels: {
                          show: true,
                          total: {
                            show: true,
                            label: "預計送貨",
                          },
                        },
                      },
                    },
                  },
                }}
                series={estimatedChartSeries}
                type="donut"
                width="100%"
                height={320}
              />
            )}
          </ChartCard>
        </Grid>
        <Grid item xs={12} md={6}>
          <ChartCard
            title="實際已送貨（依預計到貨日或實收日）"
            exportFilename="採購_實際已送貨"
            exportData={chartData.map((p) => ({ 狀態: poStatusLabelZh(p.status), 數量: p.count }))}
          >
            {loading ? (
              <Skeleton variant="rectangular" height={320} />
            ) : (
              <ApexCharts
                options={{
                  chart: {
                    type: "donut",
                    events: {
                      dataPointSelection: (_event: unknown, _chartContext: unknown, config: { dataPointIndex?: number }) => {
                        const idx = config?.dataPointIndex ?? -1;
                        if (idx < 0 || idx >= chartData.length) return;
                        const row = chartData[idx];
                        if (!row?.status) return;
                        const status = row.status;
                        deferChartClick(() => handleStatusClick(status));
                      },
                    },
                    animations: { enabled: false },
                  },
                  labels: chartData.map((p) => poStatusLabelZh(p.status)),
                  colors: chartData.map((_, i) => STATUS_DONUT_COLORS[i % STATUS_DONUT_COLORS.length]),
                  legend: { position: "bottom" },
                }}
                series={chartData.map((p) => p.count)}
                type="donut"
                width="100%"
                height={320}
              />
            )}
          </ChartCard>
        </Grid>
      </Grid>

      {selectedEstimatedBucket && (
        <Paper variant="outlined" sx={{ p: 2, mb: 2 }}>
          <Typography variant="subtitle1" fontWeight={600} gutterBottom>
            「{bucketLabelZh(selectedEstimatedBucket)}」關聯對象
          </Typography>
          <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
            條件與左側「預計送貨」圓環一致：預計到貨日 = 查詢日期（{poTargetDate}），並含上方供應商／貨品／採購單號多選。
          </Typography>
          {eaBreakdownLoading ? (
            <Box sx={{ display: "flex", justifyContent: "center", py: 3 }}>
              <CircularProgress size={28} />
            </Box>
          ) : eaBreakdown ? (
            <Grid container spacing={2}>
              <Grid item xs={12} md={4}>
                <Typography variant="subtitle2" color="primary" gutterBottom>
                  供應商
                </Typography>
                <TableContainer sx={{ maxHeight: 280 }}>
                  <Table size="small" stickyHeader>
                    <TableHead>
                      <TableRow>
                        <TableCell>編號</TableCell>
                        <TableCell>名稱</TableCell>
                        <TableCell align="right">採購單數</TableCell>
                      </TableRow>
                    </TableHead>
                    <TableBody>
                      {eaBreakdown.suppliers.length === 0 ? (
                        <TableRow>
                          <TableCell colSpan={3}>
                            <Typography variant="body2" color="text.secondary">
                              無
                            </Typography>
                          </TableCell>
                        </TableRow>
                      ) : (
                        eaBreakdown.suppliers.map((s, i) => (
                          <TableRow key={`sup-${s.supplierId ?? "null"}-${i}`}>
                            <TableCell>{s.supplierCode}</TableCell>
                            <TableCell>{s.supplierName}</TableCell>
                            <TableCell align="right">{s.poCount}</TableCell>
                          </TableRow>
                        ))
                      )}
                    </TableBody>
                  </Table>
                </TableContainer>
              </Grid>
              <Grid item xs={12} md={4}>
                <Typography variant="subtitle2" color="primary" gutterBottom>
                  貨品
                </Typography>
                <TableContainer sx={{ maxHeight: 280 }}>
                  <Table size="small" stickyHeader>
                    <TableHead>
                      <TableRow>
                        <TableCell>貨品編號</TableCell>
                        <TableCell>名稱</TableCell>
                        <TableCell align="right">採購單數</TableCell>
                        <TableCell align="right">總數量</TableCell>
                      </TableRow>
                    </TableHead>
                    <TableBody>
                      {eaBreakdown.items.length === 0 ? (
                        <TableRow>
                          <TableCell colSpan={4}>
                            <Typography variant="body2" color="text.secondary">
                              無
                            </Typography>
                          </TableCell>
                        </TableRow>
                      ) : (
                        eaBreakdown.items.map((it, i) => (
                          <TableRow key={`it-${it.itemCode}-${i}`}>
                            <TableCell>{it.itemCode}</TableCell>
                            <TableCell>{it.itemName}</TableCell>
                            <TableCell align="right">{it.poCount}</TableCell>
                            <TableCell align="right">{it.totalQty}</TableCell>
                          </TableRow>
                        ))
                      )}
                    </TableBody>
                  </Table>
                </TableContainer>
              </Grid>
              <Grid item xs={12} md={4}>
                <Typography variant="subtitle2" color="primary" gutterBottom>
                  採購單
                </Typography>
                <TableContainer sx={{ maxHeight: 280 }}>
                  <Table size="small" stickyHeader>
                    <TableHead>
                      <TableRow>
                        <TableCell>採購單號</TableCell>
                        <TableCell>供應商</TableCell>
                        <TableCell>狀態</TableCell>
                        <TableCell>訂單日期</TableCell>
                      </TableRow>
                    </TableHead>
                    <TableBody>
                      {eaBreakdown.purchaseOrders.length === 0 ? (
                        <TableRow>
                          <TableCell colSpan={4}>
                            <Typography variant="body2" color="text.secondary">
                              無
                            </Typography>
                          </TableCell>
                        </TableRow>
                      ) : (
                        eaBreakdown.purchaseOrders.map((po) => (
                          <TableRow key={po.purchaseOrderId}>
                            <TableCell>{po.purchaseOrderNo}</TableCell>
                            <TableCell>{`${po.supplierCode} ${po.supplierName}`.trim()}</TableCell>
                            <TableCell>{poStatusLabelZh(po.status)}</TableCell>
                            <TableCell>{po.orderDate}</TableCell>
                          </TableRow>
                        ))
                      )}
                    </TableBody>
                  </Table>
                </TableContainer>
              </Grid>
            </Grid>
          ) : null}
        </Paper>
      )}

      {(selectedEstimatedBucket || selectedStatus != null) && (
        <Stack spacing={1} sx={{ mb: 2 }}>
          {selectedEstimatedBucket && (
            <Alert severity="info" variant="outlined">
              下方圖表已依「預計送貨」篩選：{bucketLabelZh(selectedEstimatedBucket)}
              （預計到貨日 = 查詢日期，並含多選；此時不再套用右側「實際已送貨」狀態；再點同一扇形可取消）。
            </Alert>
          )}
          {selectedStatus != null && (
            <Alert severity="info" variant="outlined">
              下方圖表已依「實際已送貨」所選狀態：{poStatusLabelZh(selectedStatus)}（再點同一狀態可取消）。
            </Alert>
          )}
        </Stack>
      )}

      <ChartCard
        title={`${lowerChartsTitlePrefix} 的貨品摘要（code / 名稱）${lowerChartsDefaultStatusHint}${
          selectedItemCode ? ` — 已選貨品：${selectedItemCode}` : ""
        }`}
        exportFilename={`採購單_貨品摘要_${selectedEstimatedBucket ?? effectiveStatus}`}
        exportData={itemsSummary.map((i) => ({
          貨品: i.itemCode,
          名稱: i.itemName,
          訂購數量: i.orderedQty,
          已收貨: i.receivedQty,
          UOM: i.uom,
        }))}
      >
        {drillQueryOpts === null ? (
          <Typography color="text.secondary">無符合交集的篩選（請調整上方條件或圖表點選）</Typography>
        ) : itemsSummaryLoading ? (
          <Box sx={{ display: "flex", justifyContent: "center", py: 4 }}>
            <CircularProgress size={28} />
          </Box>
        ) : itemsSummary.length === 0 ? (
          <Typography color="text.secondary">
            無資料（請確認訂單日期{selectedEstimatedBucket ? "與篩選" : "與狀態"}）
          </Typography>
        ) : (
          <ApexCharts
            key={itemChartKey}
            options={{
              chart: {
                type: "donut",
                events: {
                  dataPointSelection: (_event: unknown, _chartContext: unknown, config: { dataPointIndex?: number }) => {
                    const idx = config?.dataPointIndex ?? -1;
                    if (idx < 0 || idx >= itemsSummary.length) return;
                    deferChartClick(() => handleItemSummaryClick(idx));
                  },
                },
                animations: { enabled: false },
              },
              labels: itemsSummary.map((i) => `${i.itemCode} ${i.itemName}`.trim()),
              legend: { position: "bottom" },
              plotOptions: {
                pie: {
                  donut: {
                    labels: {
                      show: true,
                      total: {
                        show: true,
                        label: "貨品",
                      },
                    },
                  },
                },
              },
            }}
            series={itemsSummary.map((i) => i.orderedQty)}
            type="donut"
            width="100%"
            height={380}
          />
        )}
      </ChartCard>

      <ChartCard
        title={`${lowerChartsTitlePrefix} 的供應商分佈${filterHint ? `（${filterHint}）` : ""}`}
        exportFilename={`採購單_供應商_${selectedEstimatedBucket ?? effectiveStatus}`}
        exportData={supplierChartData.map((s) => ({
          供應商: s.supplier,
          採購單數: s.count,
          總數量: s.totalQty,
        }))}
      >
        {drillQueryOpts === null ? (
          <Typography color="text.secondary">無符合交集的篩選</Typography>
        ) : poDetailsLoading ? (
          <Box sx={{ display: "flex", justifyContent: "center", py: 4 }}>
            <CircularProgress size={28} />
          </Box>
        ) : supplierChartData.length === 0 ? (
          <Typography color="text.secondary">無供應商資料（請先確認上方貨品篩選或日期）</Typography>
        ) : (
          <ApexCharts
            key={supplierChartKey}
            options={{
              chart: {
                type: "donut",
                events: {
                  dataPointSelection: (_event: unknown, _chartContext: unknown, config: { dataPointIndex?: number }) => {
                    const idx = config?.dataPointIndex ?? -1;
                    if (idx < 0 || idx >= supplierChartData.length) return;
                    const row = supplierChartData[idx];
                    if (!row.supplierId && !row.supplierCode?.trim()) return;
                    deferChartClick(() => handleSupplierClick(row));
                  },
                },
                animations: { enabled: false },
              },
              labels: supplierChartData.map((s) => s.supplier),
              legend: { position: "bottom" },
            }}
            series={supplierChartData.map((s) => s.totalQty)}
            type="donut"
            width="100%"
            height={360}
          />
        )}
      </ChartCard>

      <ChartCard
        title={`${lowerChartsTitlePrefix} 的採購單（點擊柱可看明細）${lowerChartsDefaultStatusHint}`}
        exportFilename={`採購單_PO_${selectedEstimatedBucket ?? effectiveStatus}`}
        exportData={poDetails.map((p) => ({
          採購單號: p.purchaseOrderNo,
          供應商: `${p.supplierCode} ${p.supplierName}`.trim(),
          總數量: p.totalQty,
          項目數: p.itemCount,
          訂單日期: p.orderDate,
        }))}
      >
        {drillQueryOpts === null ? (
          <Typography color="text.secondary">無符合交集的篩選</Typography>
        ) : poDetailsLoading ? (
          <Box sx={{ display: "flex", justifyContent: "center", py: 4 }}>
            <CircularProgress size={28} />
          </Box>
        ) : poDetails.length === 0 ? (
          <Typography color="text.secondary">
            無採購單。請確認該「訂單日期」是否有此狀態的採購單。
          </Typography>
        ) : (
          <ApexCharts
            key={poChartKey}
            options={{
              chart: {
                type: "bar",
                events: {
                  dataPointSelection: (_event: unknown, _chartContext: unknown, config: { dataPointIndex?: number }) => {
                    const idx = config?.dataPointIndex ?? -1;
                    if (idx < 0 || idx >= poDetails.length) return;
                    const po = poDetails[idx];
                    deferChartClick(() => void handlePoClick(po));
                  },
                },
                animations: { enabled: false },
              },
              xaxis: { categories: poDetails.map((p) => p.purchaseOrderNo) },
              dataLabels: { enabled: false },
            }}
            series={[
              {
                name: "總數量",
                data: poDetails.map((p) => p.totalQty),
              },
            ]}
            type="bar"
            width="100%"
            height={360}
          />
        )}
      </ChartCard>

      {selectedPo && (
        <ChartCard
          title={`採購單 ${selectedPo.purchaseOrderNo} 行明細（貨品）`}
          exportFilename={`採購單_貨品_${selectedPo.purchaseOrderNo}`}
          exportData={poLineItems.map((i) => ({
            貨品: i.itemCode,
            名稱: i.itemName,
            訂購數量: i.orderedQty,
            已收貨: i.receivedQty,
            待收貨: i.pendingQty,
            UOM: i.uom,
          }))}
        >
          {poLineItemsLoading ? (
            <Box sx={{ display: "flex", justifyContent: "center", py: 4 }}>
              <CircularProgress size={28} />
            </Box>
          ) : (
            <ApexCharts
              options={{
                chart: { type: "bar" },
                xaxis: { categories: poLineItems.map((i) => `${i.itemCode} ${i.itemName}`.trim()) },
                plotOptions: { bar: { horizontal: true } },
                dataLabels: { enabled: false },
              }}
              series={[
                { name: "訂購數量", data: poLineItems.map((i) => i.orderedQty) },
                { name: "待收貨", data: poLineItems.map((i) => i.pendingQty) },
              ]}
              type="bar"
              width="100%"
              height={Math.max(320, poLineItems.length * 38)}
            />
          )}
        </ChartCard>
      )}
    </Box>
  );
}
