import React, { useEffect, useMemo, useRef, useState } from "react";
import { Edit, MapPin, MoreHorizontal } from "lucide-react";
import { Button } from "../ui/button";
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 { Switch } from "../ui/switch";
import { toast } from "sonner";
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
import {
  Pagination,
  PaginationContent,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
} from "../ui/pagination";
import { createLocation, deleteLocation, getLocations, updateLocation } from "../../services/locationService";
import type { LocationCreateInput, LocationDto } from "../../types/location";

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}`;
}

export function LocationsView() {
  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 [keyword, setKeyword] = useState("");
  const [partner, setPartner] = useState<string>("all");
  const [groupName, setGroupName] = useState<string>("all");
  const [locationPick, setLocationPick] = useState<string>("all");

  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]);

  // Options derived from current result set (no dedicated endpoints provided in doc).
  const partnerOptions = useMemo(() => {
    const s = new Set<string>();
    for (const x of locations) {
      const v = (x.partner ?? "").trim();
      if (v) s.add(v);
    }
    return ["all", ...Array.from(s).sort((a, b) => a.localeCompare(b))];
  }, [locations]);

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

  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(() => {
    // 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 {
        // 统一约定：SkipCount 传“页码(从1开始)”
        const skipCount = Math.max(1, pageIndex);
        const effectiveKeyword = locationPick !== "all" ? locationPick : debouncedKeyword;
        const res = await getLocations(
          {
            skipCount,
            maxResultCount: pageSize,
            keyword: effectiveKeyword || 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();
  }, [debouncedKeyword, partner, groupName, locationPick, pageIndex, pageSize, refreshSeq]);

  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);
  };

  return (
    <div className="h-full flex flex-col">
      {/* Toolbar - no white background; spacing matches Labels (main p-8 only) */}
      <div className="pb-4">
        <div className="flex flex-col gap-4">
          {/* Toolbar: Search + Filters + Actions in one row, no "Search" label */}
          <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="Partner" />
              </SelectTrigger>
              <SelectContent>
                {partnerOptions.map((p) => (
                  <SelectItem key={p} value={p}>
                    {p === "all" ? "Partner (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="Group" />
              </SelectTrigger>
              <SelectContent>
                {groupOptions.map((g) => (
                  <SelectItem key={g} value={g}>
                    {g === "all" ? "Group (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" />
            <Tooltip>
              <TooltipTrigger asChild>
                <span>
                  <Button disabled variant="outline" className="h-10 border border-gray-300 rounded-md text-gray-900 px-4 bg-white hover:bg-gray-50 shrink-0">
                    Bulk Import
                  </Button>
                </span>
              </TooltipTrigger>
              <TooltipContent>Not supported yet</TooltipContent>
            </Tooltip>
            <Tooltip>
              <TooltipTrigger asChild>
                <span>
                  <Button disabled variant="outline" className="h-10 border border-gray-300 rounded-md text-gray-900 px-4 bg-white hover:bg-gray-50 shrink-0">
                    Bulk Export
                  </Button>
                </span>
              </TooltipTrigger>
              <TooltipContent>Not supported yet</TooltipContent>
            </Tooltip>
            <Tooltip>
              <TooltipTrigger asChild>
                <span>
                  <Button disabled variant="outline" className="h-10 border border-gray-300 rounded-md text-gray-900 px-4 bg-white hover:bg-gray-50 shrink-0">
                    Bulk Edit
                  </Button>
                </span>
              </TooltipTrigger>
              <TooltipContent>Not supported yet</TooltipContent>
            </Tooltip>
            <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>

      {/* Content Area - same padding as Labels (relies on main p-8) */}
      <div className="flex-1 overflow-auto pt-6">
        <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">
                <TableHead className="text-gray-900 font-bold border-r">Partner</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">Group</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">Location ID</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">Location Name</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">Street</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">City</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">State</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">Country</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">Zip Code</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">Phone</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">Email</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">GPS</TableHead>
                <TableHead className="text-gray-900 font-bold border-r">Active</TableHead>
                <TableHead className="text-gray-900 font-bold text-center">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {loading ? (
                <TableRow>
                  <TableCell colSpan={14} className="text-center text-sm text-gray-500 py-10">
                    Loading...
                  </TableCell>
                </TableRow>
              ) : locations.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={14} className="text-center text-sm text-gray-500 py-10">
                    No results.
                  </TableCell>
                </TableRow>
              ) : (
                locations.map((loc) => (
                  <TableRow key={loc.id}>
                    <TableCell className="border-r text-gray-600 max-w-[140px] truncate">{toDisplay(loc.partner)}</TableCell>
                    <TableCell className="border-r text-gray-600 max-w-[140px] truncate">{toDisplay(loc.groupName)}</TableCell>
                    <TableCell className="border-r font-numeric text-gray-600">{toDisplay(loc.locationCode ?? loc.id)}</TableCell>
                    <TableCell className="border-r font-medium text-black">{toDisplay(loc.locationName)}</TableCell>
                    <TableCell className="border-r text-gray-600 max-w-[140px] truncate">{toDisplay(loc.street)}</TableCell>
                    <TableCell className="border-r text-gray-600">{toDisplay(loc.city)}</TableCell>
                    <TableCell className="border-r text-gray-600">{toDisplay(loc.stateCode)}</TableCell>
                    <TableCell className="border-r text-gray-600">{toDisplay(loc.country)}</TableCell>
                    <TableCell className="border-r text-gray-600 font-numeric">{toDisplay(loc.zipCode)}</TableCell>
                    <TableCell className="border-r text-gray-600 whitespace-nowrap">{toDisplay(loc.phone)}</TableCell>
                    <TableCell className="border-r text-gray-600 text-sm max-w-[180px] truncate">{toDisplay(loc.email)}</TableCell>
                    <TableCell className="border-r text-gray-500 font-numeric text-xs">{formatGps(loc.latitude, loc.longitude)}</TableCell>
                    <TableCell className="border-r">
                      <Badge className={loc.state ? "bg-green-600" : "bg-gray-400"}>
                        {loc.state ? "Yes" : "No"}
                      </Badge>
                    </TableCell>
                    <TableCell className="text-center">
                      <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 h-9 px-2 font-normal text-red-600 hover:text-red-700 hover:bg-red-50"
                            onClick={() => openDelete(loc)}
                          >
                            Delete
                          </Button>
                        </PopoverContent>
                      </Popover>
                    </TableCell>
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </div>
      </div>

      <div className="pt-4">
        <div className="flex items-center justify-between text-sm text-gray-600">
          <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>

      <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();
        }}
      />
    </div>
  );
}

// --- Sub-components ---

function CreateLocationDialog({
  open,
  onOpenChange,
  onCreated,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onCreated: () => void;
}) {
  const [submitting, setSubmitting] = useState(false);
  const [form, setForm] = useState<LocationCreateInput>({
    partner: "",
    groupName: "",
    locationCode: "",
    locationName: "",
    street: "",
    city: "",
    stateCode: "",
    country: "",
    zipCode: "",
    phone: "",
    email: "",
    latitude: null,
    longitude: null,
    state: true,
  });

  const resetForm = () => {
    setForm({
      partner: "",
      groupName: "",
      locationCode: "",
      locationName: "",
      street: "",
      city: "",
      stateCode: "",
      country: "",
      zipCode: "",
      phone: "",
      email: "",
      latitude: null,
      longitude: null,
      state: true,
    });
  };

  useEffect(() => {
    if (!open) {
      resetForm();
      setSubmitting(false);
    }
  }, [open]);

  const canSubmit = useMemo(() => {
    return form.locationCode.trim().length > 0 && form.locationName.trim().length > 0;
  }, [form.locationCode, form.locationName]);

  const submit = async () => {
    if (!canSubmit) {
      toast.error("Please fill in required fields.", {
        description: "Location ID and Location Name are required.",
      });
      return;
    }
    setSubmitting(true);
    try {
      await createLocation({
        ...form,
        locationCode: form.locationCode.trim(),
        locationName: form.locationName.trim(),
        partner: form.partner?.trim() ? form.partner.trim() : null,
        groupName: form.groupName?.trim() ? form.groupName.trim() : null,
        street: form.street?.trim() ? form.street.trim() : null,
        city: form.city?.trim() ? form.city.trim() : null,
        stateCode: form.stateCode?.trim() ? form.stateCode.trim() : null,
        country: form.country?.trim() ? form.country.trim() : null,
        zipCode: form.zipCode?.trim() ? form.zipCode.trim() : null,
        phone: form.phone?.trim() ? form.phone.trim() : null,
        email: form.email?.trim() ? form.email.trim() : 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>Partner</Label>
              <Input
                placeholder="e.g. Global Foods Inc."
                value={form.partner ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, partner: e.target.value }))}
              />
            </div>
            <div className="space-y-2">
              <Label>Group</Label>
              <Input
                placeholder="e.g. East Coast Region"
                value={form.groupName ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, groupName: e.target.value }))}
              />
            </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 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 ?? "",
    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: "",
    latitude: null,
    longitude: null,
    state: true,
  });

  useEffect(() => {
    if (open && location) {
      setForm(fromDtoToForm(location));
      setSubmitting(false);
    }
    if (!open) setSubmitting(false);
  }, [open, location]);

  const canSubmit = useMemo(() => {
    return form.locationCode.trim().length > 0 && form.locationName.trim().length > 0;
  }, [form.locationCode, form.locationName]);

  const submit = async () => {
    if (!location?.id) return;
    if (!canSubmit) {
      toast.error("Please fill in required fields.", {
        description: "Location ID and Location Name are required.",
      });
      return;
    }

    setSubmitting(true);
    try {
      await updateLocation(location.id, {
        ...form,
        locationCode: form.locationCode.trim(),
        locationName: form.locationName.trim(),
        partner: form.partner?.trim() ? form.partner.trim() : null,
        groupName: form.groupName?.trim() ? form.groupName.trim() : null,
        street: form.street?.trim() ? form.street.trim() : null,
        city: form.city?.trim() ? form.city.trim() : null,
        stateCode: form.stateCode?.trim() ? form.stateCode.trim() : null,
        country: form.country?.trim() ? form.country.trim() : null,
        zipCode: form.zipCode?.trim() ? form.zipCode.trim() : null,
        phone: form.phone?.trim() ? form.phone.trim() : null,
        email: form.email?.trim() ? form.email.trim() : 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>Partner</Label>
              <Input
                placeholder="e.g. Global Foods Inc."
                value={form.partner ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, partner: e.target.value }))}
              />
            </div>
            <div className="space-y-2">
              <Label>Group</Label>
              <Input
                placeholder="e.g. East Coast Region"
                value={form.groupName ?? ""}
                onChange={(e) => setForm((p) => ({ ...p, groupName: e.target.value }))}
              />
            </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 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"
            variant="destructive"
            disabled={submitting}
            onClick={submit}
          >
            {submitting ? "Deleting..." : "Delete"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
