import { useMemo, useState } from "react";
import { Button, Group, Modal, Stack, Text } from "@mantine/core";
import { DateInput } from "@mantine/dates";
import { Ship, Upload } from "lucide-react";
import toast from "react-hot-toast";

import {
  DoCollectionDateFields,
  doDatesComplete,
  toIsoDate,
  useDoCollectionDates,
} from "@/components/contracts/DoCollectionDateFields";
import { PhasedFileDropzone } from "@/components/contracts/PhasedFileDropzone";
import { findWorkflowFile } from "@/components/contracts/PhasedUploadedFileRow";
import { contractsService } from "@/services/contracts.service";
import { bookingsService } from "@/services/bookings.service";
import type { Freight } from "@edr/types";

export type GlClearanceUploadKind = "do" | "ro";

export interface GlClearanceUploadModalProps {
  opened: boolean;
  kind: GlClearanceUploadKind | null;
  onClose: () => void;
  entityId: string;
  isBooking: boolean;
  workflowFiles?: Freight.ClearanceWorkflowFile[];
  vesselDepartureDate?: string | null;
  /** Previously recorded DO dates, so a replace opens pre-filled. */
  vesselArrivalDate?: string | null;
  doCollectedDate?: string | null;
  onSuccess?: () => void;
  onPreview?: (file: { name: string; url: string }) => void;
}

export function GlClearanceUploadModal({
  opened,
  kind,
  onClose,
  entityId,
  isBooking,
  workflowFiles = [],
  vesselDepartureDate,
  vesselArrivalDate,
  doCollectedDate,
  onSuccess,
  onPreview,
}: GlClearanceUploadModalProps) {
  const [file, setFile] = useState<File | null>(null);
  const [vesselDate, setVesselDate] = useState<Date | null>(
    vesselDepartureDate ? new Date(vesselDepartureDate) : null,
  );
  const [doDates, setDoDates] = useDoCollectionDates({
    vesselArrivalDate,
    doCollectedDate,
  });
  const [loading, setLoading] = useState(false);
  // Earliest selectable vessel date (today, local) — refreshed on each open.
  const todayISODate = useMemo(() => {
    if (!opened) return undefined;
    const now = new Date();
    const tz = now.getTimezoneOffset() * 60000;
    return new Date(now.getTime() - tz).toISOString().slice(0, 10);
  }, [opened]);

  const isDo = kind === "do";
  const isRo = kind === "ro";
  const replaceMode = isDo
    ? Boolean(findWorkflowFile(workflowFiles, "delivery_order"))
    : Boolean(findWorkflowFile(workflowFiles, "release_order"));

  const close = () => {
    setFile(null);
    onClose();
  };

  const submit = async () => {
    if (!file || !kind) return;
    if (isRo && !vesselDate) {
      toast.error("Vessel departure date is required.");
      return;
    }
    if (isDo && !doDatesComplete(doDates)) {
      toast.error("Vessel arrival date and DO collected date are both required.");
      return;
    }

    setLoading(true);
    try {
      if (isDo) {
        const dates = {
          vesselArrivalDate: toIsoDate(doDates.vesselArrival)!,
          doCollectedDate: toIsoDate(doDates.doCollected)!,
        };
        if (isBooking) {
          await bookingsService.uploadDeliveryOrder(entityId, file, dates);
        } else {
          await contractsService.uploadDeliveryOrder(entityId, file, dates);
        }
        toast.success(replaceMode ? "Delivery Order updated" : "Delivery Order uploaded");
      } else {
        const iso = vesselDate!.toISOString().slice(0, 10);
        const result = isBooking
          ? await bookingsService.uploadReleaseOrder(entityId, file, iso)
          : await contractsService.uploadReleaseOrder(entityId, file, iso);
        if (result.hold) {
          toast.error(result.holdReason ?? "Vessel date too soon");
        } else {
          toast.success(replaceMode ? "Release Order updated" : "Release Order uploaded");
        }
      }
      setFile(null);
      onSuccess?.();
      close();
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Upload failed");
    } finally {
      setLoading(false);
    }
  };

  return (
    <Modal
      opened={opened && kind != null}
      onClose={close}
      title={
        <Group gap={8}>
          <Ship size={18} />
          <Text fw={700}>{isDo ? "Upload Delivery Order" : "Upload Release Order"}</Text>
        </Group>
      }
      radius="md"
      size="md"
    >
      <Stack gap="md">
        <Text size="sm" c="dimmed">
          {isDo
            ? "Upload the Djibouti Delivery Order (DO) and record when the vessel arrived and when the DO was collected. Both dates are required."
            : "Upload the Release Order and confirm the vessel departure date."}
        </Text>

        {isRo ? (
          <DateInput
            label="Vessel departure date"
            value={vesselDate}
            onChange={(v) => setVesselDate(v ? new Date(v) : null)}
            minDate={todayISODate}
            size="sm"
            required
          />
        ) : (
          <DoCollectionDateFields value={doDates} onChange={setDoDates} />
        )}

        <PhasedFileDropzone
          label={isDo ? "Delivery Order file" : "Release Order file"}
          description={isDo ? "Any file type." : "PDF or image."}
          accept={isDo ? "*/*" : undefined}
          value={file}
          onChange={setFile}
          replaceMode={replaceMode}
          onPreview={onPreview}
        />

        <Group justify="flex-end" gap="sm">
          <Button variant="default" onClick={close} disabled={loading}>
            Cancel
          </Button>
          <Button
            color="edr-green"
            loading={loading}
            disabled={
              !file ||
              (isRo && !vesselDate) ||
              (isDo && !doDatesComplete(doDates))
            }
            leftSection={<Upload size={16} />}
            onClick={() => void submit()}
          >
            {replaceMode
              ? isDo
                ? "Replace DO"
                : "Replace RO"
              : isDo
                ? "Upload DO"
                : "Upload RO"}
          </Button>
        </Group>
      </Stack>
    </Modal>
  );
}
