"use client";

import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import EditOutlined from "@mui/icons-material/EditOutlined";
import DeleteOutline from "@mui/icons-material/DeleteOutline";
import Add from "@mui/icons-material/Add";
import {
  Alert,
  Box,
  Button,
  CircularProgress,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  FormControl,
  IconButton,
  InputLabel,
  MenuItem,
  Select,
  type SelectChangeEvent,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TextField,
  Typography,
} from "@mui/material";
import {
  fetchDoFloorSettingsClient,
  fetchSupplierComboClient,
  postSettingClient,
  type ShopComboRow,
} from "@/app/api/settings/deliveryOrderFloor/client";
import {
  SETTING_DO_FLOOR_SUPPLIERS_2F,
  SETTING_DO_FLOOR_SUPPLIERS_4F,
} from "@/app/api/settings/deliveryOrderFloor/constants";

function normalizeCodesCsv(raw: string): string {
  return raw
    .split(",")
    .map((s) => s.trim())
    .filter(Boolean)
    .join(",");
}

/** 顯示為 `[XXX, YYY]`；無代碼時為 `[]` */
function formatBracketList(codesCsv: string): string {
  const n = normalizeCodesCsv(codesCsv);
  if (!n) return "[]";
  return `[${n.split(",").join(", ")}]`;
}

type EditFloor = "2F" | "4F";

type FloorRow = { code: string; name: string };

function findSupplierRow(combo: ShopComboRow[], raw: string): ShopComboRow | undefined {
  const t = raw.trim();
  if (!t) return undefined;
  const lower = t.toLowerCase();
  const exact = combo.find((r) => r.code?.trim() === t);
  if (exact) return exact;
  return combo.find((r) => (r.code?.trim().toLowerCase() ?? "") === lower);
}

function csvToFloorRows(csv: string, combo: ShopComboRow[]): FloorRow[] {
  const n = normalizeCodesCsv(csv);
  if (!n) return [];
  return n.split(",").map((code) => {
    const hit = findSupplierRow(combo, code);
    const canonical = hit?.code?.trim() || code;
    return { code: canonical, name: hit?.name?.trim() || "" };
  });
}

function floorRowsToCsv(rows: FloorRow[]): string {
  return rows.map((r) => r.code.trim()).filter(Boolean).join(",");
}

const DeliveryOrderFloorSettings: React.FC = () => {
  const { t } = useTranslation("deliveryOrderFloor");
  const saveInFlightRef = useRef(false);
  const addInFlightRef = useRef(false);

  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);

  const [codes2F, setCodes2F] = useState("");
  const [codes4F, setCodes4F] = useState("");

  const [editOpen, setEditOpen] = useState(false);
  const [editFloor, setEditFloor] = useState<EditFloor>("2F");
  const [dialogSaving, setDialogSaving] = useState(false);
  const [comboLoading, setComboLoading] = useState(false);
  const [supplierCombo, setSupplierCombo] = useState<ShopComboRow[] | null>(null);
  const [draftRows2F, setDraftRows2F] = useState<FloorRow[]>([]);
  const [draftRows4F, setDraftRows4F] = useState<FloorRow[]>([]);

  const [addOpen, setAddOpen] = useState(false);
  const [addCodeInput, setAddCodeInput] = useState("");
  const [addError, setAddError] = useState<string | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    setSuccess(null);
    try {
      const floor = await fetchDoFloorSettingsClient();
      setCodes2F(floor.suppliers2F);
      setCodes4F(floor.suppliers4F);
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    void load();
  }, [load]);

  const display2F = useMemo(() => formatBracketList(codes2F), [codes2F]);
  const display4F = useMemo(() => formatBracketList(codes4F), [codes4F]);

  const currentDraftRows = editFloor === "2F" ? draftRows2F : draftRows4F;
  const setCurrentDraftRows = editFloor === "2F" ? setDraftRows2F : setDraftRows4F;

  const openEdit = async (floor: EditFloor) => {
    setEditFloor(floor);
    setEditOpen(true);
    setError(null);
    setSuccess(null);
    setAddOpen(false);
    setAddCodeInput("");
    setAddError(null);
    setComboLoading(true);
    try {
      const combo = await fetchSupplierComboClient();
      setSupplierCombo(combo);
      setDraftRows2F(csvToFloorRows(codes2F, combo));
      setDraftRows4F(csvToFloorRows(codes4F, combo));
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : String(e));
      setDraftRows2F([]);
      setDraftRows4F([]);
      setSupplierCombo(null);
    } finally {
      setComboLoading(false);
    }
  };

  const closeEdit = () => {
    if (dialogSaving) return;
    setEditOpen(false);
    setAddOpen(false);
    setAddCodeInput("");
    setAddError(null);
  };

  const saveCurrentFloor = async () => {
    if (saveInFlightRef.current) return;
    saveInFlightRef.current = true;
    setDialogSaving(true);
    setError(null);
    setSuccess(null);
    try {
      const rows = editFloor === "2F" ? draftRows2F : draftRows4F;
      const normalized = normalizeCodesCsv(floorRowsToCsv(rows));
      const key =
        editFloor === "2F" ? SETTING_DO_FLOOR_SUPPLIERS_2F : SETTING_DO_FLOOR_SUPPLIERS_4F;
      await postSettingClient(key, normalized);
      if (editFloor === "2F") setCodes2F(normalized);
      else setCodes4F(normalized);
      setSuccess(t("Saved"));
      setEditOpen(false);
      setAddOpen(false);
      setAddCodeInput("");
      setAddError(null);
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : String(e));
    } finally {
      setDialogSaving(false);
      saveInFlightRef.current = false;
    }
  };

  const onFloorSelectChange = (e: SelectChangeEvent<EditFloor>) => {
    setEditFloor(e.target.value as EditFloor);
    setAddOpen(false);
    setAddCodeInput("");
    setAddError(null);
  };

  const removeRow = (code: string) => {
    const next = currentDraftRows.filter((r) => r.code !== code);
    setCurrentDraftRows(next);
  };

  const openAddMapping = () => {
    if (!supplierCombo?.length) {
      setError(t("Supplier list unavailable"));
      return;
    }
    setAddCodeInput("");
    setAddError(null);
    setAddOpen(true);
  };

  const closeAdd = () => {
    if (addInFlightRef.current) return;
    setAddOpen(false);
    setAddCodeInput("");
    setAddError(null);
  };

  const confirmAddMapping = () => {
    if (addInFlightRef.current) return;
    addInFlightRef.current = true;
    setAddError(null);
    try {
      const raw = addCodeInput.trim();
      if (!raw) {
        setAddError(t("Enter supplier code"));
        return;
      }
      const hit = findSupplierRow(supplierCombo ?? [], raw);
      if (!hit?.code) {
        setAddError(t("Supplier code not found"));
        return;
      }
      const canonical = hit.code.trim();
      const otherRows = editFloor === "2F" ? draftRows4F : draftRows2F;
      if (currentDraftRows.some((r) => r.code.toLowerCase() === canonical.toLowerCase())) {
        setAddError(t("Duplicate in floor"));
        return;
      }
      if (otherRows.some((r) => r.code.toLowerCase() === canonical.toLowerCase())) {
        setAddError(t("Duplicate in other floor"));
        return;
      }
      const name = hit.name?.trim() || "";
      setCurrentDraftRows([...currentDraftRows, { code: canonical, name }]);
      setAddOpen(false);
      setAddCodeInput("");
    } finally {
      addInFlightRef.current = false;
    }
  };

  if (loading) {
    return (
      <Stack alignItems="center" py={4}>
        <CircularProgress />
      </Stack>
    );
  }

  return (
    <Stack spacing={3}>
      <Typography variant="body2" color="text.secondary">
        {t("Intro")}
      </Typography>

      {error ? <Alert severity="error">{error}</Alert> : null}
      {success ? <Alert severity="success">{success}</Alert> : null}

      <Stack spacing={2}>
        <Box
          sx={{
            display: "flex",
            alignItems: "center",
            gap: 2,
            flexWrap: "wrap",
            py: 1.5,
            px: 0,
            borderBottom: 1,
            borderColor: "divider",
          }}
        >
          <Typography component="span" variant="subtitle1" sx={{ minWidth: 120, fontWeight: 600 }}>
            {t("2F supplier")}
          </Typography>
          <Typography
            component="span"
            variant="body1"
            sx={{ fontFamily: "monospace", flex: 1, minWidth: 0, wordBreak: "break-all" }}
          >
            {display2F}
          </Typography>
          <IconButton
            aria-label={t("Edit 2F")}
            color="primary"
            edge="end"
            onClick={() => void openEdit("2F")}
            size="small"
          >
            <EditOutlined />
          </IconButton>
        </Box>

        <Box
          sx={{
            display: "flex",
            alignItems: "center",
            gap: 2,
            flexWrap: "wrap",
            py: 1.5,
            px: 0,
            borderBottom: 1,
            borderColor: "divider",
          }}
        >
          <Typography component="span" variant="subtitle1" sx={{ minWidth: 120, fontWeight: 600 }}>
            {t("4F supplier")}
          </Typography>
          <Typography
            component="span"
            variant="body1"
            sx={{ fontFamily: "monospace", flex: 1, minWidth: 0, wordBreak: "break-all" }}
          >
            {display4F}
          </Typography>
          <IconButton
            aria-label={t("Edit 4F")}
            color="primary"
            edge="end"
            onClick={() => void openEdit("4F")}
            size="small"
          >
            <EditOutlined />
          </IconButton>
        </Box>
      </Stack>

      <Dialog open={editOpen} onClose={closeEdit} fullWidth maxWidth="md">
        <DialogTitle>{t("Edit dialog title")}</DialogTitle>
        <DialogContent>
          <Stack spacing={2} sx={{ pt: 1 }}>
            <Stack
              direction={{ xs: "column", sm: "row" }}
              spacing={2}
              alignItems={{ xs: "stretch", sm: "center" }}
              flexWrap="wrap"
            >
              <FormControl size="small" sx={{ minWidth: 160 }}>
                <InputLabel id="do-floor-edit-floor-label">{t("Floor label")}</InputLabel>
                <Select
                  labelId="do-floor-edit-floor-label"
                  label={t("Floor label")}
                  value={editFloor}
                  onChange={onFloorSelectChange}
                  disabled={dialogSaving || comboLoading}
                >
                  <MenuItem value="2F">2F</MenuItem>
                  <MenuItem value="4F">4F</MenuItem>
                </Select>
              </FormControl>
              <Button
                variant="outlined"
                color="primary"
                onClick={() => void saveCurrentFloor()}
                disabled={dialogSaving || comboLoading}
                sx={{ alignSelf: { xs: "stretch", sm: "center" } }}
              >
                {dialogSaving ? <CircularProgress size={22} /> : t("Save")}
              </Button>
              <Box sx={{ flex: 1 }} />
              <Button
                variant="contained"
                color="primary"
                startIcon={<Add />}
                onClick={openAddMapping}
                disabled={dialogSaving || comboLoading || !supplierCombo?.length}
                sx={{ alignSelf: { xs: "stretch", sm: "center" } }}
              >
                {t("Add mapping")}
              </Button>
            </Stack>

            {comboLoading ? (
              <Stack alignItems="center" py={4}>
                <CircularProgress size={32} />
              </Stack>
            ) : (
              <TableContainer sx={{ maxHeight: 360, border: 1, borderColor: "divider", borderRadius: 1 }}>
                <Table size="small" stickyHeader>
                  <TableHead>
                    <TableRow>
                      <TableCell sx={{ fontWeight: 700 }}>{t("Col code")}</TableCell>
                      <TableCell sx={{ fontWeight: 700 }}>{t("Col name")}</TableCell>
                      <TableCell sx={{ fontWeight: 700, width: 100 }}>{t("Col type")}</TableCell>
                      <TableCell align="right" sx={{ fontWeight: 700, width: 88 }}>
                        {t("Col actions")}
                      </TableCell>
                    </TableRow>
                  </TableHead>
                  <TableBody>
                    {currentDraftRows.length === 0 ? (
                      <TableRow>
                        <TableCell colSpan={4}>
                          <Typography variant="body2" color="text.secondary">
                            {t("Empty floor list")}
                          </Typography>
                        </TableCell>
                      </TableRow>
                    ) : (
                      currentDraftRows.map((row) => (
                        <TableRow key={row.code} hover>
                          <TableCell sx={{ fontFamily: "monospace" }}>{row.code}</TableCell>
                          <TableCell>
                            {row.name || (
                              <Typography component="span" color="text.secondary">
                                {t("Unknown supplier name")}
                              </Typography>
                            )}
                          </TableCell>
                          <TableCell>{editFloor}</TableCell>
                          <TableCell align="right">
                            <IconButton
                              aria-label={t("Delete row")}
                              color="error"
                              size="small"
                              onClick={() => removeRow(row.code)}
                              disabled={dialogSaving}
                            >
                              <DeleteOutline fontSize="small" />
                            </IconButton>
                          </TableCell>
                        </TableRow>
                      ))
                    )}
                  </TableBody>
                </Table>
              </TableContainer>
            )}
          </Stack>
        </DialogContent>
        <DialogActions sx={{ px: 3, pb: 2 }}>
          <Button onClick={closeEdit} disabled={dialogSaving}>
            {t("Cancel")}
          </Button>
        </DialogActions>
      </Dialog>

      <Dialog open={addOpen} onClose={closeAdd} fullWidth maxWidth="xs">
        <DialogTitle>{t("Add mapping title")}</DialogTitle>
        <DialogContent>
          <Stack spacing={2} sx={{ pt: 1 }}>
            <TextField
              autoFocus
              fullWidth
              size="small"
              label={t("Col code")}
              value={addCodeInput}
              onChange={(e) => {
                setAddCodeInput(e.target.value);
                setAddError(null);
              }}
              placeholder={t("Add code placeholder")}
            />
            {addError ? <Alert severity="error">{addError}</Alert> : null}
          </Stack>
        </DialogContent>
        <DialogActions>
          <Button onClick={closeAdd}>{t("Cancel")}</Button>
          <Button variant="contained" onClick={confirmAddMapping}>
            {t("Add confirm")}
          </Button>
        </DialogActions>
      </Dialog>
    </Stack>
  );
};

export default DeliveryOrderFloorSettings;
