import {
  Alert,
  Badge,
  Button,
  Group,
  Loader,
  Modal,
  Stack,
  Text,
  TextInput,
  UnstyledButton,
} from "@mantine/core";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { CheckCircle2, Info } from "lucide-react";
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import { useNavigate } from "react-router-dom";

import { api } from "@/services/api";
import { bookingsService } from "@/services/bookings.service";

type ApproveDeliveryModalProps = {
  bookingId: string;
  opened: boolean;
  onClose: () => void;
  onApproved?: () => void;
};

const errorMessage = (error: unknown) => {
  const data = (error as { response?: { data?: { message?: string | string[] } } })
    ?.response?.data;
  if (Array.isArray(data?.message)) return data.message.join(", ");
  if (data?.message) return data.message;
  return error instanceof Error ? error.message : "Could not approve delivery";
};

const downloadBlob = (blob: Blob, filename: string) => {
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  link.remove();
  URL.revokeObjectURL(url);
};

/**
 * Approve-delivery flow: open the handover document for the customer to review,
 * then sign it with their typed full name (saved signature applied when present).
 * Self-haul: one booking-level handover, signed once. EDR last-mile: one
 * handover per delivering truck — the customer signs each; when the last one is
 * signed the delivery completes automatically.
 */
export function ApproveDeliveryModal({
  bookingId,
  opened,
  onClose,
  onApproved,
}: ApproveDeliveryModalProps) {
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const [pdfUrl, setPdfUrl] = useState<string | null>(null);
  const [signerName, setSignerName] = useState("");
  const [selectedId, setSelectedId] = useState<string | null>(null);

  const { data: handovers } = useQuery({
    queryKey: ["booking-handovers", bookingId],
    queryFn: () => bookingsService.listBookingHandovers(bookingId),
    enabled: opened && Boolean(bookingId),
    staleTime: 0,
  });

  // Per-truck mode: any EDR last-mile handover means one signature per truck.
  const edrMode = (handovers ?? []).some((h) => h.mileType === "EDR_LAST_MILE");
  const unsigned = (handovers ?? []).filter((h) => !h.signedAt);
  const selected =
    (handovers ?? []).find((h) => h.id === selectedId && !h.signedAt) ?? unsigned[0] ?? null;

  const {
    data: docBlob,
    isLoading,
    isError,
  } = useQuery({
    queryKey: ["booking-handover-doc", bookingId, edrMode ? selected?.id : "booking"],
    queryFn: () =>
      bookingsService.downloadBookingHandoverDocument(
        bookingId,
        edrMode ? selected?.id : undefined,
      ),
    enabled: opened && Boolean(bookingId) && (!edrMode || Boolean(selected)),
    staleTime: 0,
  });

  useEffect(() => {
    if (!docBlob) {
      setPdfUrl(null);
      return;
    }
    const url = URL.createObjectURL(docBlob);
    setPdfUrl(url);
    return () => URL.revokeObjectURL(url);
  }, [docBlob]);

  const invalidateBooking = () =>
    Promise.all([
      queryClient.invalidateQueries({
        queryKey: api.bookings.get.queryKey({ id: bookingId }),
      }),
      queryClient.invalidateQueries({ queryKey: api.bookings.list.queryKey() }),
      queryClient.invalidateQueries({ queryKey: ["companies", "getDashboard"] }),
    ]);

  const onSignError = (error: unknown) => {
    const message = errorMessage(error);
    toast.error(message);
    if (message.toLowerCase().includes("save your signature")) {
      onClose();
      navigate("/signature");
    } else if (/demurrage|storage|warehouse invoice|fully paid/i.test(message)) {
      onClose();
      navigate("/billing");
    }
  };

  const handoverMutation = useMutation(
    api.bookings.downloadHandoverDocument.mutationOptions(),
  );

  // Booking-level (self-haul) approval — signs every handover at once.
  const approve = useMutation({
    ...api.bookings.approveDelivery.mutationOptions(),
    onSuccess: async (result) => {
      try {
        const signed = await handoverMutation.mutateAsync({
          inventoryId: result.inventoryId,
        });
        downloadBlob(signed, `handover-${bookingId}.pdf`);
        toast.success("Delivery approved and signed handover downloaded");
      } catch {
        toast.success("Delivery approved and handover signed");
        toast.error("Signed handover document could not be downloaded");
      }
      await invalidateBooking();
      onApproved?.();
      onClose();
    },
    onError: onSignError,
  });

  // Per-truck (EDR last-mile) signature — one handover at a time.
  const signOne = useMutation({
    mutationFn: ({ handoverId, name }: { handoverId: string; name: string }) =>
      bookingsService.signHandover(handoverId, name),
    onSuccess: async (result) => {
      await queryClient.invalidateQueries({
        queryKey: ["booking-handovers", bookingId],
      });
      setSelectedId(null);
      if (result.allSigned) {
        toast.success("All handovers signed — delivery confirmed");
        await invalidateBooking();
        onApproved?.();
        onClose();
      } else {
        toast.success("Handover signed — please sign the remaining truck(s)");
      }
    },
    onError: onSignError,
  });

  const busy = approve.isPending || handoverMutation.isPending || signOne.isPending;

  return (
    <Modal
      opened={opened}
      onClose={onClose}
      title="Approve delivery — review & sign the handover"
      size="xl"
      centered
    >
      <Stack gap="md">
        <Alert color="blue" variant="light" icon={<Info size={16} />}>
          <Text size="sm">
            {edrMode
              ? "Your goods were delivered by EDR truck(s). Review and sign the handover for each truck to confirm you received the goods — delivery completes once every truck is signed."
              : "Review the handover document below, then type your full name to sign and confirm you received the goods. Your saved signature is applied automatically if you have one."}
          </Text>
        </Alert>

        {edrMode && (handovers?.length ?? 0) > 0 && (
          <Stack gap={4}>
            {handovers!.map((h) => (
              <UnstyledButton
                key={h.id}
                onClick={() => !h.signedAt && setSelectedId(h.id)}
                style={{
                  padding: "8px 12px",
                  borderRadius: 8,
                  border:
                    selected?.id === h.id
                      ? "1px solid var(--mantine-color-edr-green-6)"
                      : "1px solid var(--mantine-color-gray-3)",
                  cursor: h.signedAt ? "default" : "pointer",
                }}
              >
                <Group justify="space-between" wrap="nowrap">
                  <Text size="sm" fw={600}>
                    {h.truckPlate ? `Truck ${h.truckPlate}` : "Booking handover"} —{" "}
                    {h.reference}
                  </Text>
                  <Badge color={h.signedAt ? "green" : "yellow"} variant="light">
                    {h.signedAt ? `Signed${h.signerName ? ` — ${h.signerName}` : ""}` : "Awaiting signature"}
                  </Badge>
                </Group>
              </UnstyledButton>
            ))}
          </Stack>
        )}

        {isLoading ? (
          <Group justify="center" py="xl">
            <Loader size="sm" />
            <Text size="sm" c="dimmed">
              Loading handover document…
            </Text>
          </Group>
        ) : isError || !pdfUrl ? (
          <Text size="sm" c="red">
            Could not load the handover document. It may not be generated yet.
          </Text>
        ) : (
          <iframe
            title="Handover document"
            src={pdfUrl}
            style={{
              width: "100%",
              height: "60vh",
              border: "1px solid var(--mantine-color-gray-3)",
              borderRadius: 8,
            }}
          />
        )}

        <TextInput
          label="Your full name"
          placeholder="e.g. Abebe Kebede"
          required
          value={signerName}
          onChange={(e) => setSignerName(e.currentTarget.value)}
          disabled={busy}
        />

        <Group justify="flex-end">
          <Button variant="default" onClick={onClose} disabled={busy}>
            Cancel
          </Button>
          <Button
            color="edr-green"
            leftSection={<CheckCircle2 size={16} />}
            loading={busy}
            disabled={
              isLoading ||
              isError ||
              !signerName.trim() ||
              (edrMode && !selected)
            }
            onClick={() =>
              edrMode && selected
                ? signOne.mutate({ handoverId: selected.id, name: signerName.trim() })
                : approve.mutate({ id: bookingId, signerName: signerName.trim() })
            }
          >
            {edrMode && selected?.truckPlate
              ? `Sign for truck ${selected.truckPlate}`
              : "Approve & sign delivery"}
          </Button>
        </Group>
      </Stack>
    </Modal>
  );
}
