import { api } from "@/services/api";
import { companiesService } from "@/services/companies.service";
import { getMinFiles } from "@/types/fileUploadSettings";
import type { ProfileResponse } from "@/types/profile";
import { SmartFileInput } from "@edr/ui-common";
import {
  Button,
  Card,
  Center,
  Group,
  Text,
  Title,
} from "@mantine/core";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import {
  ArrowRight,
  CheckCircle2,
  FileCheck,
  Loader2,
  UploadCloud,
  XCircle,
} from "lucide-react";
import { useState } from "react";

interface TabDocumentsProps {
  profile: ProfileResponse;
  mode?: "edit" | "onboarding";
  onContinue?: () => void;
}

export default function TabDocuments({ profile, mode = "edit", onContinue }: TabDocumentsProps) {
  const queryClient = useQueryClient();
  const [documentFiles, setDocumentFiles] = useState<Record<string, File | File[] | null>>({});

  const docSettingQuery = useQuery(
    api.fileUploadSettings.getByCode.queryOptions({
      input: { code: "customer_file_documents" },
    }),
  );

  const docUploadMutation = useMutation({
    mutationFn: (files: Record<string, File | File[] | null>) =>
      companiesService.uploadDocuments(profile.companyId, files),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: api.companies.getProfile.queryKey() });
    },
  });

  const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});

  const handleFilesChange = (next: Record<string, File | File[] | null>) => {
    setDocumentFiles(next);
    // Clear required-field errors for any field that now has a file.
    setFieldErrors((prev) => {
      if (Object.keys(prev).length === 0) return prev;
      const updated = { ...prev };
      for (const key of Object.keys(updated)) {
        const v = next[key];
        const hasValue = Array.isArray(v) ? v.length > 0 : v != null;
        if (hasValue) delete updated[key];
      }
      return updated;
    });
  };

  // Array-aware: an emptied multi-file field is `[]`, which must not count.
  const hasFiles = Object.values(documentFiles).some((f) =>
    Array.isArray(f) ? f.length > 0 : f != null,
  );

  const validateRequired = (): Record<string, string> => {
    const errs: Record<string, string> = {};
    for (const field of docSettingQuery.data?.fields ?? []) {
      const min = getMinFiles(field);
      if (min <= 0) continue;
      const v = documentFiles[field.fileKey];
      const count = Array.isArray(v) ? v.length : v ? 1 : 0;
      if (count < min) {
        errs[field.fileKey] = `${field.fileLabel} is required`;
      }
    }
    return errs;
  };

  return (
    <Card padding="lg">
      <Group gap="sm" mb="xs">
        <FileCheck size={20} />
        <Title order={3}>Documents</Title>
      </Group>
      <Text c="edr-muted" size="sm" mb="lg">
        Upload and manage required business documents
      </Text>

      {docSettingQuery.isLoading ? (
        <Center py="xl">
          <Loader2 size={24} className="animate-spin" />
        </Center>
      ) : !docSettingQuery.data ? (
        <Text c="edr-muted" size="sm" ta="center" py="md">
          No document requirements configured for your account.
        </Text>
      ) : (
        <SmartFileInput
          file={docSettingQuery.data}
          value={documentFiles}
          onChange={handleFilesChange}
          errors={fieldErrors}
        />
      )}

      {docSettingQuery.data && (
        <Group
          justify="space-between"
          mt="lg"
          pt="md"
          style={{ borderTop: "1px solid var(--mantine-color-edr-border-0)" }}
        >
          <Group gap="xs">
            {docUploadMutation.isSuccess && (
              <Group gap={6} c="green">
                <CheckCircle2 size={16} />
                <Text size="sm" fw={500}>
                  {mode === "onboarding" ? "Saved successfully" : "Documents uploaded successfully"}
                </Text>
              </Group>
            )}
            {docUploadMutation.isError && (
              <Group gap={6} c="red">
                <XCircle size={16} />
                <Text size="sm" fw={500}>Upload failed</Text>
              </Group>
            )}
          </Group>
          {mode === "onboarding" ? (
            <Button
              type="button"
              leftSection={<ArrowRight size={16} />}
              loading={docUploadMutation.isPending}
              onClick={() => {
                const validationErrors = validateRequired();
                if (Object.keys(validationErrors).length > 0) {
                  setFieldErrors(validationErrors);
                  return;
                }
                if (hasFiles) {
                  docUploadMutation.mutate(documentFiles, {
                    onSuccess: () => onContinue?.(),
                  });
                } else {
                  onContinue?.();
                }
              }}
            >
              Continue
            </Button>
          ) : (
            <Button
              type="button"
              leftSection={<UploadCloud size={16} />}
              loading={docUploadMutation.isPending}
              disabled={!hasFiles}
              onClick={() => {
                if (!hasFiles) return;
                docUploadMutation.mutate(documentFiles);
              }}
            >
              Upload Documents
            </Button>
          )}
        </Group>
      )}
    </Card>
  );
}
