import { Box, Group, Loader, Stack, Text } from "@mantine/core";
import { SmartFileInput } from "@edr/ui-common";
import { CheckCircle2, Download, FileText } from "lucide-react";

import { IconSquare } from "../BookingDetailPage/components/Documents";
import { downloadStoredFile } from "@/services/files.service";
import { labelForDocCode } from "./resubmitDocs";
import type { ResubmitFlowController } from "./useResubmitFlow";

/**
 * Document section for resubmitting a CHANGES_REQUESTED booking.
 *
 * Mirrors the new-booking document step: the fields come from the company's
 * onboarding document setting (TIN, license, ID, passport, …) rendered via
 * SmartFileInput. Documents already submitted on the booking are shown as an
 * "on file" reference; the customer uploads here only to replace one, or to fill
 * any required field that has nothing on file yet (those block resubmit).
 */
export function ResubmitDocuments({ flow }: { flow: ResubmitFlowController }) {
  const { files, setting, settingLoading, documents, setDocuments, fieldErrors } =
    flow;

  // One reference row per distinct doc already on the booking (latest upload).
  const onFile = dedupeLatestByCode(files);

  return (
    <Stack gap="lg">
      {onFile.length > 0 && (
        <Stack gap={8}>
          <Text fz={13} fw={700} c="#10202F">
            Already submitted
          </Text>
          {onFile.map((file) => (
            <Group
              key={file.id}
              gap={12}
              align="center"
              wrap="nowrap"
              className="rounded-xl"
              style={{ border: "1px solid #E6ECF2", padding: "10px 14px" }}
            >
              <Box
                style={{
                  flexShrink: 0,
                  width: 34,
                  height: 34,
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "center",
                  borderRadius: 9,
                  backgroundColor: "#EAF1FB",
                  color: "#2E5B96",
                }}
              >
                <FileText size={17} />
              </Box>
              <Box style={{ minWidth: 0, flex: 1 }}>
                <Text fz="13px" fw={600} c="#10202F" truncate>
                  {labelForDocCode(file.code)}
                </Text>
                <Text fz="12px" c="dimmed" truncate>
                  {file.name}
                </Text>
              </Box>
              <Group gap={8} wrap="nowrap">
                <Group gap={5} c="#0A6F4D">
                  <CheckCircle2 size={14} />
                  <Text fz="11.5px" fw={600} c="#0A6F4D">
                    On file
                  </Text>
                </Group>
                <IconSquare
                  icon={<Download size={15} />}
                  onClick={() => void downloadStoredFile(file.id, file.name)}
                />
              </Group>
            </Group>
          ))}
        </Stack>
      )}

      <Box>
        <Text fz={13} fw={700} c="#10202F" mb="xs">
          Update documents
        </Text>
        <Text fz="12px" c="dimmed" mb="sm">
          Replace any document you need to change. Documents marked required must
          be on file before you can resubmit.
        </Text>

        {settingLoading ? (
          <Group justify="center" py="lg">
            <Loader size="sm" color="edr-green" />
          </Group>
        ) : setting ? (
          <SmartFileInput
            file={setting}
            value={documents}
            onChange={setDocuments}
            errors={fieldErrors}
          />
        ) : (
          <Text fz="13px" c="dimmed">
            No document requirements are configured for your account. You can
            resubmit using the documents already on file.
          </Text>
        )}
      </Box>
    </Stack>
  );
}

type BookingFile = ResubmitFlowController["files"][number];

/** Keep one row per code (the most recent upload, i.e. last in the array). */
function dedupeLatestByCode(files: BookingFile[]): BookingFile[] {
  const order: string[] = [];
  const latest = new Map<string, BookingFile>();
  for (const file of files) {
    if (!latest.has(file.code)) order.push(file.code);
    latest.set(file.code, file);
  }
  return order.map((code) => latest.get(code)!);
}
