import { Box, Button, Group, Paper, Stack, Text } from "@mantine/core";
import { FileText, Upload } from "lucide-react";
import type { ReactNode } from "react";
import type { Freight } from "@edr/types";

import { PhasedFileDropzone } from "@/components/contracts/PhasedFileDropzone";
import { PhasedUploadedFileRow, findWorkflowFile } from "@/components/contracts/PhasedUploadedFileRow";

export interface PhasedDocumentUploadFieldProps {
  fields: Array<{ key: string; label: string }>;
  files: Record<string, File | null>;
  onChange: (key: string, file: File | null) => void;
  workflowFiles?: Freight.ClearanceWorkflowFile[];
  helperText: string;
  /** Extra inputs rendered above the dropzones (e.g. required DO dates). */
  extraFields?: ReactNode;
  replaceMode?: boolean;
  loading?: boolean;
  disabled?: boolean;
  submitLabel?: string;
  onSubmit: () => void;
  onViewFile?: (file: { name: string; url: string }) => void;
  onDownloadFile?: (file: { id: string; name: string }) => void;
}

/** Consistent phased customs document upload with drag-and-drop, preview, and uploaded rows. */
export function PhasedDocumentUploadField({
  fields,
  files,
  onChange,
  workflowFiles = [],
  helperText,
  extraFields,
  replaceMode = false,
  loading = false,
  disabled = false,
  submitLabel,
  onSubmit,
  onViewFile,
  onDownloadFile,
}: PhasedDocumentUploadFieldProps) {
  const hasStaged = Object.values(files).some(Boolean);
  const uploaded = fields
    .map((f) => ({ ...f, file: findWorkflowFile(workflowFiles, f.key) }))
    .filter((f) => f.file);
  const multiField = fields.length > 1;

  return (
    <Stack gap="md">
      {uploaded.length > 0 ? (
        <Stack gap={8}>
          <Text size="xs" fw={700} c="dimmed" tt="uppercase">
            Current file{uploaded.length > 1 ? "s" : ""}
          </Text>
          {uploaded.map((row) => (
            <PhasedUploadedFileRow
              key={row.key}
              label={row.label}
              file={row.file!}
              onView={onViewFile}
              onDownload={onDownloadFile}
            />
          ))}
        </Stack>
      ) : null}

      <Paper withBorder radius="md" p="md" bg="var(--mantine-color-gray-0)">
        <Group gap={8} mb="sm" wrap="nowrap">
          <Box
            c="edr-green"
            style={{
              width: 32,
              height: 32,
              borderRadius: 8,
              display: "flex",
              alignItems: "center",
              justifyContent: "center",
              background: "var(--mantine-color-edr-green-1)",
            }}
          >
            <FileText size={16} />
          </Box>
          <Box>
            <Text size="sm" fw={700}>
              {replaceMode ? "Replace document" : "Upload document"}
            </Text>
            <Text size="xs" c="dimmed">
              {helperText}
            </Text>
          </Box>
        </Group>

        <Stack gap="md">
          {extraFields}
          {fields.map((f) => (
            <PhasedFileDropzone
              key={f.key}
              label={multiField ? f.label : "Choose file"}
              description={
                multiField
                  ? uploaded.some((u) => u.key === f.key)
                    ? "Drop a new file to replace the current one."
                    : `Upload ${f.label} (optional if another declaration type is provided).`
                  : undefined
              }
              value={files[f.key] ?? null}
              onChange={(file) => onChange(f.key, file)}
              replaceMode={replaceMode || uploaded.some((u) => u.key === f.key)}
              onPreview={onViewFile}
            />
          ))}
        </Stack>
      </Paper>

      <Button
        color="edr-green"
        loading={loading}
        disabled={disabled || !hasStaged}
        leftSection={<Upload size={16} />}
        onClick={onSubmit}
        fullWidth
      >
        {submitLabel ?? (replaceMode ? "Replace document" : "Upload document")}
      </Button>
    </Stack>
  );
}
