import React, { useEffect, useMemo, useRef, useState } from "react";
import { Edit, MapPin, MoreHorizontal, Trash2 } from "lucide-react";
import { Button } from "../ui/button";
import { Checkbox } from "../ui/checkbox";
import { Input } from "../ui/input";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "../ui/table";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "../ui/dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "../ui/select";
import { Label } from "../ui/label";
import { Badge } from "../ui/badge";
import { cn } from "../ui/utils";
import { Switch } from "../ui/switch";
import { toast } from "sonner";
import { skipCountForPage } from "../../lib/paginationQuery";
import { useCategoryScopeAuth } from "../../hooks/useCategoryScopeAuth";
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
import {
  Pagination,
  PaginationContent,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
} from "../ui/pagination";
import {
  createLocation,
  deleteLocation,
  downloadLocationImportTemplate,
  exportLocationsExcel,
  getLocations,
  importLocationsBatch,
  updateLocation,
} from "../../services/locationService";
import { getPartners } from "../../services/partnerService";
import { getGroups } from "../../services/groupService";
import type { LocationCreateInput, LocationDto } from "../../types/location";
import type { GroupListItem } from "../../types/group";
import type { PartnerListItem } from "../../types/partner";
import { BatchImportDialog } from "../bulk/batch-import-dialog";
import { LocationBulkEditPage } from "./location-bulk-edit-page";

const LOCATION_PG_NONE = "__none__";

async function loadActivePartnerOptions(signal: AbortSignal): Promise<PartnerListItem[]> {
  const out: PartnerListItem[] = [];
  let page = 1;
  const size = 100;
  for (;;) {
    const res = await getPartners({ skipCount: page, maxResultCount: size, state: true }, signal);
    out.push(...(res.items ?? []));
    if (!res.items || res.items.length < size) break;
    page += 1;
    if (page > 200) break;
  }
  const m = new Map<string, PartnerListItem>();
  for (const p of out) if (p.id && !m.has(p.id)) m.set(p.id, p);
  return Array.from(m.values());
}

async function loadActiveGroupsForPartner(partnerId: string, signal: AbortSignal): Promise<GroupListItem[]> {
  const out: GroupListItem[] = [];
  let page = 1;
  const size = 100;
  for (;;) {
    const res = await getGroups(
      { skipCount: page, maxResultCount: size, partnerId, state: true },
      signal,
    );
    out.push(...(res.items ?? []));
    if (!res.items || res.items.length < size) break;
    page += 1;
    if (page > 200) break;
  }
  const m = new Map<string, GroupListItem>();
  for (const g of out) if (g.id && !m.has(g.id)) m.set(g.id, g);
  return Array.from(m.values());
}

function toDisplay(v: string | null | undefined): string {
  const s = (v ?? "").trim();
  return s ? s : "N/A";
}

function formatGps(lat: number | null | undefined, lng: number | null | undefined): string {
  if (lat === null || lat === undefined || lng === null || lng === undefined) return "N/A";
  if (!Number.isFinite(lat) || !Number.isFinite(lng)) return "N/A";
  return `${lat}, ${lng}`;
}

/**
 * 门店表单红框区域：Location ID / Name、地址、联系方式（Company、Region、Active、GPS 不要求）
 * 仅校验是否填写，不校验邮箱/电话格式。
 */
function getLocationRedBoxValidationErrors(form: LocationCreateInput): string[] {
  const errs: string[] = [];
  if (!form.locationCode.trim()) errs.push("Location ID");
  if (!form.locationName.trim()) errs.push("Location Name");
  if (!(form.street ?? "").trim()) errs.push("Street");
  if (!(form.city ?? "").trim()) errs.push("City");
  if (!(form.stateCode ?? "").trim()) errs.push("State");
  if (!(form.country ?? "").trim()) errs.push("Country");
  if (!(form.zipCode ?? "").trim()) errs.push("Zip Code");
  if (!(form.phone ?? "").trim()) errs.push("Phone Number");
  if (!(form.email ?? "").trim()) errs.push("Email");
  return errs;
}

export type LocationsViewProps = {
  /**
   * 嵌入 Account Management 时：将「搜索/筛选/操作」条交给父组件排版（例如放在 Tab 上方）。
   * 传入的 `toolbar` 为门店管理原有工具栏节点，父组件应将其与 Tab 等一并渲染。
   */
  renderBeforeTabs?: (toolbar: React.ReactNode) => React.ReactNode;
  /**
   * 为 false 时隐藏新建、批量导入/批量编辑、行勾选及编辑/删除（非平台管理员）。
   * @default true
   */
  canMutateLocations?: boolean;
};

export function LocationsView({ renderBeforeTabs, canMutateLocations = true }: LocationsViewProps = {}) {
  const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);
  const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
  const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
  const [editingLocation, setEditingLocation] = useState<LocationDto | null>(null);
  const [deletingLocation, setDeletingLocation] = useState<LocationDto | null>(null);
  const [locations, setLocations] = useState<LocationDto[]>([]);
  const [loading, setLoading] = useState(false);
  const [total, setTotal] = useState(0);
  const [refreshSeq, setRefreshSeq] = useState(0);
  const [actionsOpenForId, setActionsOpenForId] = useState<string | null>(null);
  const [selectedIds, setSelectedIds] = useState<Set<string>>(() => new Set());
  const [bulkImportOpen, setBulkImportOpen] = useState(false);
  const [locationBulkEditPage, setLocationBulkEditPage] = useState(false);
  const [bulkEditSeed, setBulkEditSeed] = useState<LocationDto[]>([]);
  const [tmplDownloading, setTmplDownloading] = useState(false);
  const [excelExporting, setExcelExporting] = useState(false);

  const [keyword, setKeyword] = useState("");
  const [partner, setPartner] = useState<string>("all");
  const [groupName, setGroupName] = useState<string>("all");
  const [locationPick, setLocationPick] = useState<string>("all");

  /** 筛选栏：公司 / 区域选项来自接口，而非当前门店分页结果去重 */
  const [filterPartnerOptions, setFilterPartnerOptions] = useState<PartnerListItem[]>([]);
  const [filterGroupOptions, setFilterGroupOptions] = useState<GroupListItem[]>([]);

  const [pageIndex, setPageIndex] = useState(1);
  const [pageSize, setPageSize] = useState(10);

  const abortRef = useRef<AbortController | null>(null);
  const keywordTimerRef = useRef<number | null>(null);
  const [debouncedKeyword, setDebouncedKeyword] = useState("");

  useEffect(() => {
    if (keywordTimerRef.current) window.clearTimeout(keywordTimerRef.current);
    keywordTimerRef.current = window.setTimeout(() => setDebouncedKeyword(keyword.trim()), 300);
    return () => {
      if (keywordTimerRef.current) window.clearTimeout(keywordTimerRef.current);
    };
  }, [keyword]);

  const listKeyword = useMemo(
    () => (locationPick !== "all" ? locationPick : debouncedKeyword.trim()),
    [locationPick, debouncedKeyword],
  );

  // 门店下拉仍来自当前分页结果（无独立 lookup 接口时保留）
  const partnerOptions = useMemo(() => {
    const names = filterPartnerOptions
      .map((p) => (p.partnerName ?? "").trim())
      .filter(Boolean)
      .sort((a, b) => a.localeCompare(b));
    return ["all", ...names];
  }, [filterPartnerOptions]);

  const groupOptions = useMemo(() => {
    const names = filterGroupOptions
      .map((g) => (g.groupName ?? "").trim())
      .filter(Boolean)
      .sort((a, b) => a.localeCompare(b));
    return ["all", ...names];
  }, [filterGroupOptions]);

  const locationOptions = useMemo(() => {
    const s = new Set<string>();
    for (const x of locations) {
      const v = (x.locationCode ?? "").trim();
      if (v) s.add(v);
    }
    return ["all", ...Array.from(s).sort((a, b) => a.localeCompare(b))];
  }, [locations]);

  const totalPages = Math.max(1, Math.ceil(total / pageSize));

  useEffect(() => {
    const ac = new AbortController();
    (async () => {
      try {
        const list = await loadActivePartnerOptions(ac.signal);
        setFilterPartnerOptions(list);
      } catch {
        if (!ac.signal.aborted) setFilterPartnerOptions([]);
      }
    })();
    return () => ac.abort();
  }, []);

  useEffect(() => {
    const ac = new AbortController();
    (async () => {
      try {
        if (partner === "all") {
          const out: GroupListItem[] = [];
          let page = 1;
          const size = 100;
          for (;;) {
            const res = await getGroups(
              { skipCount: page, maxResultCount: size, state: true },
              ac.signal,
            );
            out.push(...(res.items ?? []));
            if (!res.items || res.items.length < size) break;
            page += 1;
            if (page > 200) break;
          }
          const m = new Map<string, GroupListItem>();
          for (const g of out) if (g.id && !m.has(g.id)) m.set(g.id, g);
          setFilterGroupOptions(Array.from(m.values()));
          return;
        }
        const picked = filterPartnerOptions.find(
          (p) => (p.partnerName ?? "").trim() === partner.trim(),
        );
        if (!picked?.id) {
          setFilterGroupOptions([]);
          return;
        }
        const list = await loadActiveGroupsForPartner(picked.id, ac.signal);
        setFilterGroupOptions(list);
      } catch {
        if (!ac.signal.aborted) setFilterGroupOptions([]);
      }
    })();
    return () => ac.abort();
  }, [partner, filterPartnerOptions]);

  useEffect(() => {
    if (groupName === "all") return;
    if (!groupOptions.includes(groupName)) setGroupName("all");
  }, [groupName, groupOptions]);

  useEffect(() => {
    // When filter changes, reset to first page.
    setPageIndex(1);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [debouncedKeyword, partner, groupName, locationPick, pageSize]);

  useEffect(() => {
    const run = async () => {
      abortRef.current?.abort();
      const ac = new AbortController();
      abortRef.current = ac;

      setLoading(true);
      try {
        const skipCount = skipCountForPage(pageIndex);
        const res = await getLocations(
          {
            skipCount,
            maxResultCount: pageSize,
            keyword: listKeyword || undefined,
            partner: partner !== "all" ? partner : undefined,
            groupName: groupName !== "all" ? groupName : undefined,
          },
          ac.signal,
        );

        setLocations(res.items ?? []);
        setTotal(res.totalCount ?? 0);
      } catch (e: any) {
        if (e?.name === "AbortError") return;
        toast.error("Failed to load locations.", {
          description: e?.message ? String(e.message) : "Please try again.",
        });
        setLocations([]);
        setTotal(0);
      } finally {
        setLoading(false);
      }
    };

    run();
    return () => abortRef.current?.abort();
  }, [listKeyword, partner, groupName, locationPick, pageIndex, pageSize, refreshSeq]);

  useEffect(() => {
    setSelectedIds(new Set());
  }, [debouncedKeyword, partner, groupName, locationPick, pageIndex]);

  useEffect(() => {
    if (!canMutateLocations) {
      setLocationBulkEditPage(false);
      setBulkEditSeed([]);
      setSelectedIds(new Set());
    }
  }, [canMutateLocations]);

  const refreshList = () => setRefreshSeq((x) => x + 1);

  const openEdit = (loc: LocationDto) => {
    setActionsOpenForId(null);
    setEditingLocation(loc);
    setIsEditDialogOpen(true);
  };

  const openDelete = (loc: LocationDto) => {
    setActionsOpenForId(null);
    setDeletingLocation(loc);
    setIsDeleteDialogOpen(true);
  };

  const toolbarSection = (
    <div className={cn(!locationBulkEditPage && "pb-4", locationBulkEditPage && "hidden")}>
      <div className="flex flex-col gap-4">
        <div className="flex flex-nowrap items-center gap-3">
          <Input
            placeholder="Search"
            value={keyword}
            onChange={(e) => setKeyword(e.target.value)}
            style={{ height: 40, boxSizing: "border-box" }}
            className="border border-gray-300 rounded-md w-40 shrink-0 bg-white placeholder:text-gray-500"
          />
          <Select value={partner} onValueChange={setPartner}>
            <SelectTrigger className="w-[140px] h-10 rounded-md border border-gray-300 bg-white font-medium text-gray-900 shrink-0" style={{ height: 40, boxSizing: "border-box" }}>
              <SelectValue placeholder="Company" />
            </SelectTrigger>
            <SelectContent>
              {partnerOptions.map((p) => (
                <SelectItem key={p} value={p}>
                  {p === "all" ? "Company (All)" : p}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Select value={groupName} onValueChange={setGroupName}>
            <SelectTrigger className="w-[140px] h-10 rounded-md border border-gray-300 bg-white font-medium text-gray-900 shrink-0" style={{ height: 40, boxSizing: "border-box" }}>
              <SelectValue placeholder="Region" />
            </SelectTrigger>
            <SelectContent>
              {groupOptions.map((g) => (
                <SelectItem key={g} value={g}>
                  {g === "all" ? "Region (All)" : g}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Select value={locationPick} onValueChange={setLocationPick}>
            <SelectTrigger className="w-[140px] h-10 rounded-md border border-gray-300 bg-white font-medium text-gray-900 shrink-0" style={{ height: 40, boxSizing: "border-box" }}>
              <SelectValue placeholder="Location" />
            </SelectTrigger>
            <SelectContent>
              {locationOptions.map((x) => (
                <SelectItem key={x} value={x}>
                  {x === "all" ? "All Locations" : x}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <div className="flex-1" />
          {canMutateLocations && (
            <>
              <Button
                type="button"
                variant="outline"
                className="h-10 border border-gray-300 rounded-md text-gray-900 px-4 bg-white hover:bg-gray-50 shrink-0"
                onClick={() => setBulkImportOpen(true)}
              >
                Bulk Import
              </Button>
            </>
          )}
          <Button
            type="button"
            variant="outline"
            className="h-10 border border-gray-300 rounded-md text-gray-900 px-4 bg-white hover:bg-gray-50 shrink-0"
            disabled={excelExporting}
            onClick={async () => {
              setExcelExporting(true);
              try {
                await exportLocationsExcel({
                  keyword: listKeyword || undefined,
                  partner: partner !== "all" ? partner : undefined,
                  groupName: groupName !== "all" ? groupName : undefined,
                });
                toast.success("Export started", { description: "Your browser should download the Excel file." });
              } catch (e: unknown) {
                const msg = e instanceof Error ? e.message : "Please try again.";
                toast.error("Export failed", { description: msg });
              } finally {
                setExcelExporting(false);
              }
            }}
          >
            {excelExporting ? "Exporting…" : "Bulk Export"}
          </Button>
          {canMutateLocations && (
            <>
              <Button
                type="button"
                variant="outline"
                className="h-10 border border-gray-300 rounded-md text-gray-900 px-4 bg-white hover:bg-gray-50 shrink-0"
                onClick={() => {
                  const seed = locations.filter((l) => selectedIds.has(l.id));
                  if (seed.length === 0) {
                    toast.error("No rows selected", { description: "Use the checkboxes on the left, then open Bulk Edit." });
                    return;
                  }
                  setBulkEditSeed(seed);
                  setLocationBulkEditPage(true);
                }}
              >
                Bulk Edit
              </Button>
              <Button
                className="h-10 bg-blue-600 hover:bg-blue-700 text-white rounded-md px-6 font-medium shrink-0"
                onClick={() => setIsCreateDialogOpen(true)}
              >
                New
              </Button>
            </>
          )}
        </div>
      </div>
    </div>
  );

  const locationTableColSpan = canMutateLocations ? 15 : 14;

  const tableAndPagination = (
    <>
      <div className="flex-1 overflow-auto pt-6 min-h-0">
        <div className="bg-white border border-gray-200 shadow-sm rounded-md overflow-hidden">
          <Table>
            <TableHeader>
                <TableRow className="bg-gray-100 hover:bg-gray-100">
                  {canMutateLocations ? (
                    <TableHead className="border-r text-sm font-semibold text-gray-900 w-12 shrink-0 text-center px-3">
                      <Checkbox
                        checked={locations.length > 0 && locations.every((l) => selectedIds.has(l.id))}
                        onCheckedChange={(c) => {
                          if (c === true) setSelectedIds(new Set(locations.map((l) => l.id)));
                          else setSelectedIds(new Set());
                        }}
                        aria-label="Select all on page"
                      />
                    </TableHead>
                  ) : null}
                  <TableHead className="border-r text-sm font-semibold text-gray-900">Company</TableHead>
                <TableHead className="border-r text-sm font-semibold text-gray-900">Region</TableHead>
                <TableHead className="border-r text-sm font-semibold text-gray-900">Location ID</TableHead>
                <TableHead className="border-r text-sm font-semibold text-gray-900">Location Name</TableHead>
                <TableHead className="border-r text-sm font-semibold text-gray-900">Street</TableHead>
                <TableHead className="border-r text-sm font-semibold text-gray-900">City</TableHead>
                <TableHead className="border-r text-sm font-semibold text-gray-900">State</TableHead>
                <TableHead className="border-r text-sm font-semibold text-gray-900">Country</TableHead>
                <TableHead className="border-r text-sm font-semibold text-gray-900">Zip Code</TableHead>
                <TableHead className="border-r text-sm font-semibold text-gray-900">Phone</TableHead>
                <TableHead className="border-r text-sm font-semibold text-gray-900">Email</TableHead>
                <TableHead className="border-r text-sm font-semibold text-gray-900">GPS</TableHead>
                <TableHead className="border-r text-sm font-semibold text-gray-900">Active</TableHead>
                <TableHead className="text-sm font-semibold text-gray-900 text-center">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {loading ? (
                <TableRow>
                  <TableCell colSpan={locationTableColSpan} className="text-center text-sm font-normal text-gray-900 py-10">
                    Loading...
                  </TableCell>
                </TableRow>
              ) : locations.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={locationTableColSpan} className="text-center text-sm font-normal text-gray-900 py-10">
                    No results.
                  </TableCell>
                </TableRow>
              ) : (
                locations.map((loc) => (
                  <TableRow key={loc.id}>
                    {canMutateLocations ? (
                      <TableCell className="border-r w-12 shrink-0 text-center px-3">
                        <Checkbox
                          checked={selectedIds.has(loc.id)}
                          onCheckedChange={(c) => {
                            setSelectedIds((prev) => {
                              const n = new Set(prev);
                              if (c === true) n.add(loc.id);
                              else n.delete(loc.id);
                              return n;
                            });
                          }}
                          aria-label="Select row"
                        />
                      </TableCell>
                    ) : null}
                    <TableCell className="border-r text-sm font-normal text-gray-900 max-w-[140px] truncate">
                      {toDisplay(loc.partner)}
                    </TableCell>
                    <TableCell className="border-r text-sm font-normal text-gray-900 max-w-[140px] truncate">
                      {toDisplay(loc.groupName)}
                    </TableCell>
                    <TableCell className="border-r text-sm font-normal text-gray-900 font-numeric">
                      {toDisplay(loc.locationCode ?? loc.id)}
                    </TableCell>
                    <TableCell className="border-r text-sm font-normal text-gray-900">{toDisplay(loc.locationName)}</TableCell>
                    <TableCell className="border-r text-sm font-normal text-gray-900 max-w-[140px] truncate">
                      {toDisplay(loc.street)}
                    </TableCell>
                    <TableCell className="border-r text-sm font-normal text-gray-900">{toDisplay(loc.city)}</TableCell>
                    <TableCell className="border-r text-sm font-normal text-gray-900">{toDisplay(loc.stateCode)}</TableCell>
                    <TableCell className="border-r text-sm font-normal text-gray-900">{toDisplay(loc.country)}</TableCell>
                    <TableCell className="border-r text-sm font-normal text-gray-900 font-numeric">
                      {toDisplay(loc.zipCode)}
                    </TableCell>
                    <TableCell className="border-r text-sm font-normal text-gray-900 whitespace-nowrap">
                      {toDisplay(loc.phone)}
                    </TableCell>
                    <TableCell className="border-r text-sm font-normal text-gray-900 max-w-[180px] truncate">
                      {toDisplay(loc.email)}
                    </TableCell>
                    <TableCell className="border-r text-sm font-normal text-gray-900 font-numeric">
                      {formatGps(loc.latitude, loc.longitude)}
                    </TableCell>
                    <TableCell className="border-r">
                      <Badge
                        className={cn(
                          "text-sm font-normal",
                          loc.state ? "bg-green-600" : "bg-gray-400",
                        )}
                      >
                        {loc.state ? "Yes" : "No"}
                      </Badge>
                    </TableCell>
                    <TableCell className="text-center text-sm font-normal text-gray-900">
                      {canMutateLocations ? (
                        <Popover
                          open={actionsOpenForId === loc.id}
                          onOpenChange={(open) => setActionsOpenForId(open ? loc.id : null)}
                        >
                          <PopoverTrigger asChild>
                            <Button
                              type="button"
                              variant="ghost"
                              size="icon"
                              className="h-8 w-8"
                              aria-label="Row actions"
                            >
                              <MoreHorizontal className="h-4 w-4 text-gray-500" />
                            </Button>
                          </PopoverTrigger>
                          <PopoverContent align="end" className="w-40 p-1">
                            <Button
                              type="button"
                              variant="ghost"
                              className="w-full justify-start gap-2 h-9 px-2 font-normal"
                              onClick={() => openEdit(loc)}
                            >
                              <Edit className="w-4 h-4" />
                              Edit
                            </Button>
                            <Button
                              type="button"
                              variant="ghost"
                              className="w-full justify-start gap-2 h-9 px-2 font-normal text-red-600 hover:text-red-700 hover:bg-red-50"
                              onClick={() => openDelete(loc)}
                            >
                              <Trash2 className="w-4 h-4 shrink-0" />
                              Delete
                            </Button>
                          </PopoverContent>
                        </Popover>
                      ) : (
                        "—"
                      )}
                    </TableCell>
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </div>
      </div>

      <div className="pt-4 shrink-0">
        <div className="flex items-center justify-between text-sm font-normal text-gray-900">
          <div>
            Showing {total === 0 ? 0 : (pageIndex - 1) * pageSize + 1}-
            {Math.min(pageIndex * pageSize, total)} of {total}
          </div>
          <div className="flex items-center gap-3">
            <Select value={String(pageSize)} onValueChange={(v) => setPageSize(Number(v))}>
              <SelectTrigger className="w-[110px] h-9 rounded-md border border-gray-300 bg-white text-gray-900">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {[10, 20, 50].map((n) => (
                  <SelectItem key={n} value={String(n)}>
                    {n} / page
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <Pagination className="mx-0 w-auto justify-end">
              <PaginationContent>
                <PaginationItem>
                  <PaginationPrevious
                    href="#"
                    size="default"
                    onClick={(e) => {
                      e.preventDefault();
                      setPageIndex((p) => Math.max(1, p - 1));
                    }}
                    aria-disabled={pageIndex <= 1}
                    className={pageIndex <= 1 ? "pointer-events-none opacity-50" : ""}
                  />
                </PaginationItem>
                <PaginationItem>
                  <PaginationLink
                    href="#"
                    isActive
                    size="default"
                    onClick={(e) => e.preventDefault()}
                  >
                    Page {pageIndex} / {totalPages}
                  </PaginationLink>
                </PaginationItem>
                <PaginationItem>
                  <PaginationNext
                    href="#"
                    size="default"
                    onClick={(e) => {
                      e.preventDefault();
                      setPageIndex((p) => Math.min(totalPages, p + 1));
                    }}
                    aria-disabled={pageIndex >= totalPages}
                    className={pageIndex >= totalPages ? "pointer-events-none opacity-50" : ""}
                  />
                </PaginationItem>
              </PaginationContent>
            </Pagination>
          </div>
        </div>
      </div>
    </>
  );

  const listOrBulkMain = locationBulkEditPage ? (
    <div className="flex-1 overflow-auto pt-6 min-h-0">
      <div className="bg-white border border-gray-200 shadow-sm rounded-md overflow-hidden flex flex-col min-h-0 h-full max-h-full">
        <LocationBulkEditPage
          seed={bulkEditSeed}
          onBack={() => {
            setLocationBulkEditPage(false);
            setBulkEditSeed([]);
          }}
          onSaved={() => {
            setSelectedIds(new Set());
            refreshList();
          }}
        />
      </div>
    </div>
  ) : (
    tableAndPagination
  );

  const dialogs = (
    <>
      <CreateLocationDialog
        open={isCreateDialogOpen}
        onOpenChange={setIsCreateDialogOpen}
        onCreated={() => {
          // 新增后强制刷新一次列表；如果当前已在第一页也能刷新。
          setPageIndex(1);
          refreshList();
        }}
      />

      <EditLocationDialog
        open={isEditDialogOpen}
        location={editingLocation}
        onOpenChange={(open) => {
          setIsEditDialogOpen(open);
          if (!open) setEditingLocation(null);
        }}
        onUpdated={() => {
          // 编辑后强制刷新一次列表
          refreshList();
        }}
      />

      <DeleteLocationDialog
        open={isDeleteDialogOpen}
        location={deletingLocation}
        onOpenChange={(open) => {
          setIsDeleteDialogOpen(open);
          if (!open) setDeletingLocation(null);
        }}
        onDeleted={() => {
          refreshList();
        }}
      />

      <BatchImportDialog
        open={bulkImportOpen}
        onOpenChange={setBulkImportOpen}
        title="Bulk import locations"
        description="Upload an .xlsx file. Use the official template for correct column headers."
        downloadingTemplate={tmplDownloading}
        onDownloadTemplate={async () => {
          setTmplDownloading(true);
          try {
            await downloadLocationImportTemplate();
            toast.success("Template downloaded.");
          } catch (e: unknown) {
            const msg = e instanceof Error ? e.message : "Download failed.";
            toast.error("Template download failed", { description: msg });
          } finally {
            setTmplDownloading(false);
          }
        }}
        onImportFile={async (file) => {
          const r = await importLocationsBatch(file);
          refreshList();
          return { successCount: r.successCount, failCount: r.failCount };
        }}
      />

    </>
  );

  if (renderBeforeTabs) {
    return (
      <div className="h-full flex flex-col min-h-0">
        {renderBeforeTabs(toolbarSection)}
        <div className="flex-1 min-h-0 flex flex-col overflow-hidden">{listOrBulkMain}</div>
        {dialogs}
      </div>
    );
  }

  return (
    <div className="h-full flex flex-col min-h-0">
      {toolbarSection}
      <div className="flex-1 min-h-0 flex flex-col overflow-hidden">{listOrBulkMain}</div>
      {dialogs}
    </div>
  );
}

// --- Sub-components ---

function CreateLocationDialog({
  open,
  onOpenChange,
  onCreated,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onCreated: () => void;
}) {
  const scopeAuth = useCategoryScopeAuth();
  const [submitting, setSubmitting] = useState(false);
  const [form, setForm] = useState<LocationCreateInput>({
    partner: "",
    groupName: "",
    locationCode: "",
    locationName: "",
    street: "",
    city: "",
    stateCode: "",
    country: "",
    zipCode: "",
    phone: "",
    email: "",
    operatingHours: "",
    latitude: null,
    longitude: null,
    state: true,
  });
  const [partnerPickId, setPartnerPickId] = useState(LOCATION_PG_NONE);
  const [groupPickId, setGroupPickId] = useState(LOCATION_PG_NONE);
  const [partnerOptions, setPartnerOptions] = useState<PartnerListItem[]>([]);
  const [groupOptions, setGroupOptions] = useState<GroupListItem[]>([]);
  const [loadingPartners, setLoadingPartners] = useState(false);
  const [loadingGroups, setLoadingGroups] = useState(false);
  const createAbortRef = useRef<AbortController | null>(null);

  const resetForm = () => {
    setForm({
      partner: "",
      groupName: "",
      locationCode: "",
      locationName: "",
      street: "",
      city: "",
      stateCode: "",
      country: "",
      zipCode: "",
      phone: "",
      email: "",
      operatingHours: "",
      latitude: null,
      longitude: null,
      state: true,
    });
    setPartnerPickId(LOCATION_PG_NONE);
    setGroupPickId(LOCATION_PG_NONE);
    setPartnerOptions([]);
    setGroupOptions([]);
  };

  useEffect(() => {
    if (!open) {
      createAbortRef.current?.abort();
      resetForm();
      setSubmitting(false);
    }
  }, [open]);

  useEffect(() => {
    if (!open) return;
    createAbortRef.current?.abort();
    const ac = new AbortController();
    createAbortRef.current = ac;
    setLoadingPartners(true);
    (async () => {
      try {
        const list = await loadActivePartnerOptions(ac.signal);
        setPartnerOptions(list);
        if (!scopeAuth.requireCompanySelection) {
          const pid = scopeAuth.fixedPartnerId.trim();
          if (pid && list.some((p) => p.id === pid)) {
            setPartnerPickId(pid);
          }
        }
      } catch (e: any) {
        if (e?.name === "AbortError") return;
        toast.error("Failed to load companies.", {
          description: e?.message ? String(e.message) : "Please try again.",
        });
        setPartnerOptions([]);
      } finally {
        setLoadingPartners(false);
      }
    })();
    return () => ac.abort();
  }, [open, scopeAuth.requireCompanySelection, scopeAuth.fixedPartnerId]);

  useEffect(() => {
    if (!open || scopeAuth.requireCompanySelection || scopeAuth.loadingPartner) return;
    const pid = scopeAuth.fixedPartnerId.trim();
    if (pid && partnerOptions.some((p) => p.id === pid)) {
      setPartnerPickId(pid);
    }
  }, [open, scopeAuth.requireCompanySelection, scopeAuth.fixedPartnerId, scopeAuth.loadingPartner, partnerOptions]);

  useEffect(() => {
    if (!open || partnerPickId === LOCATION_PG_NONE) {
      setGroupOptions([]);
      setGroupPickId(LOCATION_PG_NONE);
      setLoadingGroups(false);
      return;
    }
    const ac = new AbortController();
    setLoadingGroups(true);
    (async () => {
      try {
        const list = await loadActiveGroupsForPartner(partnerPickId, ac.signal);
        setGroupOptions(list);
        setGroupPickId(LOCATION_PG_NONE);
      } catch (e: any) {
        if (e?.name === "AbortError") return;
        toast.error("Failed to load regions.", {
          description: e?.message ? String(e.message) : "Please try again.",
        });
        setGroupOptions([]);
      } finally {
        setLoadingGroups(false);
      }
    })();
    return () => ac.abort();
  }, [open, partnerPickId]);

  const submit = async () => {
    const errs = getLocationRedBoxValidationErrors(form);
    if (errs.length) {
      toast.error("Please fill in required fields.", {
        description: `Missing: ${errs.join(", ")}.`,
      });
      return;
    }
    const resolvedPartnerPickId =
      partnerPickId !== LOCATION_PG_NONE
        ? partnerPickId
        : !scopeAuth.requireCompanySelection
          ? scopeAuth.fixedPartnerId.trim()
          : "";
    const p = resolvedPartnerPickId
      ? partnerOptions.find((x) => x.id === resolvedPartnerPickId)
      : undefined;
    const g = groupPickId !== LOCATION_PG_NONE ? groupOptions.find((x) => x.id === groupPickId) : undefined;
    setSubmitting(true);
    try {
      await createLocation({
        ...form,
        locationCode: form.locationCode.trim(),
        locationName: form.locationName.trim(),
        partner: p?.partnerName?.trim() ? p.partnerName.trim() : null,
        groupName: g?.groupName?.trim() ? g.groupName.trim() : null,
        street: (form.street ?? "").trim(),
        city: (form.city ?? "").trim(),
        stateCode: (form.stateCode ?? "").trim(),
        country: (form.country ?? "").trim(),
        zipCode: (form.zipCode ?? "").trim(),
        phone: (form.phone ?? "").trim(),
        email: (form.email ?? "").trim(),
        operatingHours: (form.operatingHours ?? "").trim() || null,
        latitude: form.latitude ?? null,
        longitude: form.longitude ?? null,
      });
      toast.success("Location created.", {
        description: "The location has been added successfully.",
      });
      onOpenChange(false);
      onCreated();
    } catch (e: any) {
      toast.error("Failed to create location.", {
        description: e?.message ? String(e.message) : "Please try again.",
      });
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[600px]">
        <DialogHeader>
          <DialogTitle>Add New Location</DialogTitle>
          <DialogDescription>
            Enter the details for the new store location.
          </DialogDescription>
        </DialogHeader>
        
        <div className="grid gap-4 py-4">
          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label>Company</Label>
              <Select
                value={partnerPickId}
                onValueChange={(v) => {
                  setPartnerPickId(v);
                  setGroupPickId(LOCATION_PG_NONE);
                }}
                disabled={loadingPartners || scopeAuth.loadingPartner || !scopeAuth.requireCompanySelection}
              >
                <SelectTrigger className="h-11 rounded-xl border border-transparent bg-gray-100 px-4 font-semibold text-gray-900 data-[placeholder]:font-medium data-[placeholder]:text-gray-500">
                  <SelectValue placeholder={loadingPartners ? "Loading..." : "e.g. Global Foods Inc."} />
                </SelectTrigger>
                <SelectContent>
                  {scopeAuth.requireCompanySelection ? (
                    <SelectItem value={LOCATION_PG_NONE}>None</SelectItem>
                  ) : null}
                  {partnerOptions.map((p) => (
                    <SelectItem key={p.id} value={p.id}>
                      {p.partnerName ?? p.id}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label>Region</Label>
              <Select
                value={groupPickId}
                onValueChange={setGroupPickId}
                disabled={loadingGroups || partnerPickId === LOCATION_PG_NONE}
              >
                <SelectTrigger className="h-11 rounded-xl border border-transparent bg-gray-100 px-4 font-semibold text-gray-900 data-[placeholder]:font-medium data-[placeholder]:text-gray-500">
                  <SelectValue
                    placeholder={
                      partnerPickId === LOCATION_PG_NONE
                        ? "Select a company first"
                        : loadingGroups
                          ? "Loading..."
                          : "e.g. East Coast Region"
                    }
                  />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value={LOCATION_PG_NONE}>None</SelectItem>
                  {groupOptions.map((g) => (
                    <SelectItem key={g.id} value={g.id}>
                      {g.groupName ?? g.id}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>

          <div className="grid grid-cols-3 gap-4">
             <div className="space-y-2 col-span-1">
              <Label>Location ID *</Label>
              <Input
                placeholder="e.g. 12345"
                value={form.locationCode}
                onChange={(e) => setForm((p) => ({ ...p, locationCode: e.target.value }))}
              />
            </div>
            <div className="space-y-2 col-span-2">
              <Label>Location Name *</Label>
              <Input
                placeholder="e.g. Downtown Store"
                value={form.locationName}
                onChange={(e) => setForm((p) => ({ ...p, locationName: e.target.value }))}
              />
            </div>
          </div>

          <div className="space-y-2">
            <Label>Street *</Label>
            <Input
              placeholder="e.g. 123 Main St"
              value={form.street ?? ""}
              onChange={(e) => setForm((p) => ({ ...p, street: e.target.value }))}
            />
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label>City *</Label>
              <Input
                placeholder="e.g. New York"
                value={form.city ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, city: e.target.value }))}
              />
            </div>
            <div className="space-y-2">
              <Label>State *</Label>
              <Input
                placeholder="e.g. NY"
                value={form.stateCode ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, stateCode: e.target.value }))}
              />
            </div>
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label>Country *</Label>
              <Input
                placeholder="e.g. USA"
                value={form.country ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, country: e.target.value }))}
              />
            </div>
            <div className="space-y-2">
              <Label>Zip Code *</Label>
              <Input
                placeholder="e.g. 10001"
                value={form.zipCode ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, zipCode: e.target.value }))}
              />
            </div>
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label>Phone Number *</Label>
              <Input
                placeholder="+1 (555) 000-0000"
                value={form.phone ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, phone: e.target.value }))}
              />
            </div>
            <div className="space-y-2">
              <Label>Email *</Label>
              <Input
                placeholder="store@example.com"
                value={form.email ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, email: e.target.value }))}
              />
            </div>
          </div>

          <div className="space-y-2">
            <Label>Business hours</Label>
            <Input
              placeholder="e.g. Mon–Fri 9:00 AM – 6:00 PM"
              value={form.operatingHours ?? ""}
              onChange={(e) => setForm((p) => ({ ...p, operatingHours: e.target.value }))}
            />
          </div>

          <div className="space-y-2">
            <Label className="flex items-center gap-2">
              <MapPin className="w-4 h-4" /> GPS Coordinates
            </Label>
            <div className="grid grid-cols-2 gap-4">
              <Input
                placeholder="Latitude (e.g. 40.7128)"
                value={form.latitude === null || form.latitude === undefined ? "" : String(form.latitude)}
                onChange={(e) => {
                  const raw = e.target.value.trim();
                  setForm((p) => ({ ...p, latitude: raw ? Number(raw) : null }));
                }}
              />
              <Input
                placeholder="Longitude (e.g. -74.0060)"
                value={form.longitude === null || form.longitude === undefined ? "" : String(form.longitude)}
                onChange={(e) => {
                  const raw = e.target.value.trim();
                  setForm((p) => ({ ...p, longitude: raw ? Number(raw) : null }));
                }}
              />
            </div>
          </div>

           <div className="flex items-center gap-2 pt-2">
            <Switch
              id="loc-status"
              checked={!!form.state}
              onCheckedChange={(v) => setForm((p) => ({ ...p, state: v }))}
            />
            <Label htmlFor="loc-status">Active Location</Label>
          </div>

        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>Cancel</Button>
          <Button
            disabled={submitting}
            onClick={submit}
            className="bg-blue-600 text-white hover:bg-blue-700"
          >
            {submitting ? "Creating..." : "Create Location"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function fromDtoToForm(loc: LocationDto): LocationCreateInput {
  return {
    partner: loc.partner ?? "",
    groupName: loc.groupName ?? "",
    locationCode: loc.locationCode ?? "",
    locationName: loc.locationName ?? "",
    street: loc.street ?? "",
    city: loc.city ?? "",
    stateCode: loc.stateCode ?? "",
    country: loc.country ?? "",
    zipCode: loc.zipCode ?? "",
    phone: loc.phone ?? "",
    email: loc.email ?? "",
    operatingHours: loc.operatingHours ?? "",
    latitude: loc.latitude ?? null,
    longitude: loc.longitude ?? null,
    state: !!loc.state,
  };
}

function EditLocationDialog({
  open,
  location,
  onOpenChange,
  onUpdated,
}: {
  open: boolean;
  location: LocationDto | null;
  onOpenChange: (open: boolean) => void;
  onUpdated: () => void;
}) {
  const [submitting, setSubmitting] = useState(false);
  const [form, setForm] = useState<LocationCreateInput>({
    partner: "",
    groupName: "",
    locationCode: "",
    locationName: "",
    street: "",
    city: "",
    stateCode: "",
    country: "",
    zipCode: "",
    phone: "",
    email: "",
    operatingHours: "",
    latitude: null,
    longitude: null,
    state: true,
  });
  const [partnerPickId, setPartnerPickId] = useState(LOCATION_PG_NONE);
  const [groupPickId, setGroupPickId] = useState(LOCATION_PG_NONE);
  const [partnerOptions, setPartnerOptions] = useState<PartnerListItem[]>([]);
  const [groupOptions, setGroupOptions] = useState<GroupListItem[]>([]);
  const [loadingPartners, setLoadingPartners] = useState(false);
  const [loadingGroups, setLoadingGroups] = useState(false);
  const initialPartnerIdRef = useRef<string | typeof LOCATION_PG_NONE | "__user__">(LOCATION_PG_NONE);

  useEffect(() => {
    if (!open) {
      setSubmitting(false);
      setPartnerPickId(LOCATION_PG_NONE);
      setGroupPickId(LOCATION_PG_NONE);
      setPartnerOptions([]);
      setGroupOptions([]);
      initialPartnerIdRef.current = LOCATION_PG_NONE;
      return;
    }
    if (!location) return;
    setForm(fromDtoToForm(location));
    setSubmitting(false);
    initialPartnerIdRef.current = LOCATION_PG_NONE;
    setPartnerPickId(LOCATION_PG_NONE);
    setGroupPickId(LOCATION_PG_NONE);

    const ac = new AbortController();
    setLoadingPartners(true);
    (async () => {
      try {
        const plist = await loadActivePartnerOptions(ac.signal);
        setPartnerOptions(plist);
        const pname = (location.partner ?? "").trim().toLowerCase();
        let pid: string | typeof LOCATION_PG_NONE = LOCATION_PG_NONE;
        if (pname) {
          const hit = plist.find((p) => (p.partnerName ?? "").trim().toLowerCase() === pname);
          if (hit) pid = hit.id;
        }
        initialPartnerIdRef.current = pid;
        setPartnerPickId(pid);
      } catch (e: any) {
        if (e?.name === "AbortError") return;
        toast.error("Failed to load companies.", {
          description: e?.message ? String(e.message) : "Please try again.",
        });
        setPartnerOptions([]);
      } finally {
        setLoadingPartners(false);
      }
    })();
    return () => ac.abort();
  }, [open, location?.id]);

  useEffect(() => {
    if (!open || partnerPickId === LOCATION_PG_NONE) {
      setGroupOptions([]);
      setGroupPickId(LOCATION_PG_NONE);
      setLoadingGroups(false);
      return;
    }
    const ac = new AbortController();
    setLoadingGroups(true);
    (async () => {
      try {
        const list = await loadActiveGroupsForPartner(partnerPickId, ac.signal);
        setGroupOptions(list);
        let nextG = LOCATION_PG_NONE;
        const refPid = initialPartnerIdRef.current;
        const canAuto =
          !!location &&
          refPid !== "__user__" &&
          refPid !== LOCATION_PG_NONE &&
          partnerPickId === refPid;
        if (canAuto) {
          const gname = (location!.groupName ?? "").trim().toLowerCase();
          if (gname) {
            const hit = list.find((g) => (g.groupName ?? "").trim().toLowerCase() === gname);
            if (hit) nextG = hit.id;
          }
        }
        setGroupPickId(nextG);
      } catch (e: any) {
        if (e?.name === "AbortError") return;
        toast.error("Failed to load regions.", {
          description: e?.message ? String(e.message) : "Please try again.",
        });
        setGroupOptions([]);
      } finally {
        setLoadingGroups(false);
      }
    })();
    return () => ac.abort();
  }, [open, partnerPickId, location?.groupName, location?.id]);

  const submit = async () => {
    if (!location?.id) return;
    const errs = getLocationRedBoxValidationErrors(form);
    if (errs.length) {
      toast.error("Please fill in required fields.", {
        description: `Missing: ${errs.join(", ")}.`,
      });
      return;
    }

    const p =
      partnerPickId !== LOCATION_PG_NONE ? partnerOptions.find((x) => x.id === partnerPickId) : undefined;
    const g = groupPickId !== LOCATION_PG_NONE ? groupOptions.find((x) => x.id === groupPickId) : undefined;

    setSubmitting(true);
    try {
      await updateLocation(location.id, {
        ...form,
        locationCode: form.locationCode.trim(),
        locationName: form.locationName.trim(),
        partner: p?.partnerName?.trim() ? p.partnerName.trim() : null,
        groupName: g?.groupName?.trim() ? g.groupName.trim() : null,
        street: (form.street ?? "").trim(),
        city: (form.city ?? "").trim(),
        stateCode: (form.stateCode ?? "").trim(),
        country: (form.country ?? "").trim(),
        zipCode: (form.zipCode ?? "").trim(),
        phone: (form.phone ?? "").trim(),
        email: (form.email ?? "").trim(),
        operatingHours: (form.operatingHours ?? "").trim() || null,
        latitude: form.latitude ?? null,
        longitude: form.longitude ?? null,
      });

      toast.success("Location updated.", {
        description: "The changes have been saved successfully.",
      });
      onOpenChange(false);
      onUpdated();
    } catch (e: any) {
      toast.error("Failed to update location.", {
        description: e?.message ? String(e.message) : "Please try again.",
      });
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[600px]">
        <DialogHeader>
          <DialogTitle>Edit Location</DialogTitle>
          <DialogDescription>
            Update the details for this store location.
          </DialogDescription>
        </DialogHeader>

        <div className="grid gap-4 py-4">
          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label>Company</Label>
              <Select
                value={partnerPickId}
                onValueChange={(v) => {
                  initialPartnerIdRef.current = "__user__";
                  setPartnerPickId(v);
                  setGroupPickId(LOCATION_PG_NONE);
                }}
                disabled={loadingPartners}
              >
                <SelectTrigger className="h-11 rounded-xl border border-transparent bg-gray-100 px-4 font-semibold text-gray-900 data-[placeholder]:font-medium data-[placeholder]:text-gray-500">
                  <SelectValue placeholder={loadingPartners ? "Loading..." : "e.g. Global Foods Inc."} />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value={LOCATION_PG_NONE}>None</SelectItem>
                  {partnerOptions.map((p) => (
                    <SelectItem key={p.id} value={p.id}>
                      {p.partnerName ?? p.id}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label>Region</Label>
              <Select
                value={groupPickId}
                onValueChange={setGroupPickId}
                disabled={loadingGroups || partnerPickId === LOCATION_PG_NONE}
              >
                <SelectTrigger className="h-11 rounded-xl border border-transparent bg-gray-100 px-4 font-semibold text-gray-900 data-[placeholder]:font-medium data-[placeholder]:text-gray-500">
                  <SelectValue
                    placeholder={
                      partnerPickId === LOCATION_PG_NONE
                        ? "Select a company first"
                        : loadingGroups
                          ? "Loading..."
                          : "e.g. East Coast Region"
                    }
                  />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value={LOCATION_PG_NONE}>None</SelectItem>
                  {groupOptions.map((g) => (
                    <SelectItem key={g.id} value={g.id}>
                      {g.groupName ?? g.id}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>

          <div className="grid grid-cols-3 gap-4">
            <div className="space-y-2 col-span-1">
              <Label>Location ID *</Label>
              <Input
                placeholder="e.g. 12345"
                value={form.locationCode}
                onChange={(e) => setForm((p) => ({ ...p, locationCode: e.target.value }))}
              />
            </div>
            <div className="space-y-2 col-span-2">
              <Label>Location Name *</Label>
              <Input
                placeholder="e.g. Downtown Store"
                value={form.locationName}
                onChange={(e) => setForm((p) => ({ ...p, locationName: e.target.value }))}
              />
            </div>
          </div>

          <div className="space-y-2">
            <Label>Street *</Label>
            <Input
              placeholder="e.g. 123 Main St"
              value={form.street ?? ""}
              onChange={(e) => setForm((p) => ({ ...p, street: e.target.value }))}
            />
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label>City *</Label>
              <Input
                placeholder="e.g. New York"
                value={form.city ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, city: e.target.value }))}
              />
            </div>
            <div className="space-y-2">
              <Label>State *</Label>
              <Input
                placeholder="e.g. NY"
                value={form.stateCode ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, stateCode: e.target.value }))}
              />
            </div>
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label>Country *</Label>
              <Input
                placeholder="e.g. USA"
                value={form.country ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, country: e.target.value }))}
              />
            </div>
            <div className="space-y-2">
              <Label>Zip Code *</Label>
              <Input
                placeholder="e.g. 10001"
                value={form.zipCode ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, zipCode: e.target.value }))}
              />
            </div>
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label>Phone Number *</Label>
              <Input
                placeholder="+1 (555) 000-0000"
                value={form.phone ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, phone: e.target.value }))}
              />
            </div>
            <div className="space-y-2">
              <Label>Email *</Label>
              <Input
                placeholder="store@example.com"
                value={form.email ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, email: e.target.value }))}
              />
            </div>
          </div>

          <div className="space-y-2">
            <Label>Business hours</Label>
            <Input
              placeholder="e.g. Mon–Fri 9:00 AM – 6:00 PM"
              value={form.operatingHours ?? ""}
              onChange={(e) => setForm((p) => ({ ...p, operatingHours: e.target.value }))}
            />
          </div>

          <div className="space-y-2">
            <Label className="flex items-center gap-2">
              <MapPin className="w-4 h-4" /> GPS Coordinates
            </Label>
            <div className="grid grid-cols-2 gap-4">
              <Input
                placeholder="Latitude (e.g. 40.7128)"
                value={form.latitude === null || form.latitude === undefined ? "" : String(form.latitude)}
                onChange={(e) => {
                  const raw = e.target.value.trim();
                  setForm((p) => ({ ...p, latitude: raw ? Number(raw) : null }));
                }}
              />
              <Input
                placeholder="Longitude (e.g. -74.0060)"
                value={form.longitude === null || form.longitude === undefined ? "" : String(form.longitude)}
                onChange={(e) => {
                  const raw = e.target.value.trim();
                  setForm((p) => ({ ...p, longitude: raw ? Number(raw) : null }));
                }}
              />
            </div>
          </div>

          <div className="flex items-center gap-2 pt-2">
            <Switch
              id="loc-status-edit"
              checked={!!form.state}
              onCheckedChange={(v) => setForm((p) => ({ ...p, state: v }))}
            />
            <Label htmlFor="loc-status-edit">Active Location</Label>
          </div>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>Cancel</Button>
          <Button
            disabled={submitting}
            onClick={submit}
            className="bg-blue-600 text-white hover:bg-blue-700"
          >
            {submitting ? "Saving..." : "Save Changes"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function DeleteLocationDialog({
  open,
  location,
  onOpenChange,
  onDeleted,
}: {
  open: boolean;
  location: LocationDto | null;
  onOpenChange: (open: boolean) => void;
  onDeleted: () => void;
}) {
  const [submitting, setSubmitting] = useState(false);

  const name = useMemo(() => {
    const code = (location?.locationCode ?? "").trim();
    const n = (location?.locationName ?? "").trim();
    if (code && n) return `${code} - ${n}`;
    return code || n || "this location";
  }, [location?.locationCode, location?.locationName]);

  const submit = async () => {
    if (!location?.id) return;
    setSubmitting(true);
    try {
      await deleteLocation(location.id);
      toast.success("Location deleted.", {
        description: "The location has been removed successfully.",
      });
      onOpenChange(false);
      onDeleted();
    } catch (e: any) {
      toast.error("Failed to delete location.", {
        description: e?.message ? String(e.message) : "Please try again.",
      });
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-none" style={{ width: "30%" }}>
        <DialogHeader>
          <DialogTitle>Delete Location</DialogTitle>
          <DialogDescription>
            This action cannot be undone.
          </DialogDescription>
        </DialogHeader>

        <div className="text-sm text-gray-700">
          Are you sure you want to delete <span className="font-medium">{name}</span>?
        </div>

        <DialogFooter className="flex-row flex-wrap justify-end">
          <Button className="min-w-24" variant="outline" onClick={() => onOpenChange(false)}>Cancel</Button>
          <Button
            className="min-w-24 gap-2"
            variant="destructive"
            disabled={submitting}
            onClick={submit}
          >
            <Trash2 className="h-4 w-4 shrink-0" />
            {submitting ? "Deleting..." : "Delete"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
