import {
  Alert,
  Button,
  Group,
  Loader,
  Stack,
  Text,
  TextInput,
} from "@mantine/core";
import { useEffect, useRef } from "react";
import type { UseFormRegisterReturn } from "react-hook-form";
import { AlertCircle, CheckCircle2, Download, Info } from "lucide-react";
import { useETradeData } from "@/hooks/useETradeData";
import { extractApiError } from "@/utils/result";
import type { CompanyRegistrationData } from "@edr/types";

interface ETradeInfoProps {
  /** Current TIN value (drives button enablement). */
  tin: string;
  /** RHF registration for the TIN input — this is the form's primary TIN field. */
  register: UseFormRegisterReturn;
  /** Validation error for the TIN field, if any. */
  error?: string;
  onDataLoaded: (data: CompanyRegistrationData) => void;
}

const isValidTin = (tin: string) => tin.length === 10;

export default function ETradeInfo({
  tin,
  register,
  error,
  onDataLoaded,
}: ETradeInfoProps) {
  const mutation = useETradeData();
  const isLoading = mutation.isPending;
  const tinTaken = mutation.data?.tinTaken;
  const hasData =
    mutation.data && !mutation.data.tinTaken ? mutation.data : null;

  const handleFetch = async () => {
    if (!isValidTin(tin)) return;
    const result = await mutation.mutateAsync(tin);
    if (result && !result.tinTaken) {
      onDataLoaded(result);
    }
  };

  // Auto-fetch as soon as the TIN reaches its full 10-digit length — only
  // once per distinct value, so retyping the same TIN doesn't refetch.
  const lastFetchedTin = useRef<string | null>(null);
  useEffect(() => {
    if (isValidTin(tin) && lastFetchedTin.current !== tin) {
      lastFetchedTin.current = tin;
      handleFetch();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [tin]);

  const apiError =
    mutation.isError && mutation.error
      ? extractApiError(mutation.error)
      : null;
  // A 400 here means eTrade simply has no record for this TIN — not a
  // failure. Soft-pedal it as an FYI, not a red error, so filling in
  // manually doesn't feel like something went wrong.
  const notFound = apiError?.statusCode === 400;
  const errorMessage =
    apiError && !notFound
      ? apiError.message ||
        "We couldn't reach eTrade to fetch your company information. Please try again, or fill in the details manually below."
      : null;

  return (
    <Stack gap="md">
      <Group align="flex-start" grow>
        <TextInput
          label={
            <>
              TIN Number (10 digits){" "}
              <span style={{ color: "var(--mantine-color-red-6)" }}>*</span>
            </>
          }
          placeholder="0012345678"
          maxLength={10}
          error={error}
          {...register}
        />
        {errorMessage && (
          <Button
            variant="filled"
            color="edr-green"
            onClick={handleFetch}
            disabled={!isValidTin(tin) || isLoading}
            leftSection={
              isLoading ? <Loader size={16} /> : <Download size={16} />
            }
            mt="24px"
          >
            {isLoading ? "Getting..." : "Get Data"}
          </Button>
        )}
      </Group>

      {notFound && (
        <Alert icon={<Info size={16} />} color="gray">
          We couldn't find a matching business record for this TIN — no
          problem, just fill in the details below.
        </Alert>
      )}

      {errorMessage && (
        <Alert
          icon={<AlertCircle size={16} />}
          color="red"
          title="Couldn't fetch eTrade data"
        >
          {errorMessage}
        </Alert>
      )}

      {tinTaken && (
        <Alert
          icon={<AlertCircle size={16} />}
          color="red"
          title="TIN already registered"
        >
          This TIN is already registered to another company account. Please
          double-check the number, or contact support if you believe this is a
          mistake.
        </Alert>
      )}

      {hasData && (
        <Alert
          icon={<CheckCircle2 size={16} />}
          color="green"
          title="Company information loaded"
        >
          <Stack gap={0}>
            <Text size="sm">
              <strong>License:</strong> {hasData.licenceNumber}
            </Text>
            <Text size="sm">
              <strong>Status:</strong> {hasData.statusDescription}
            </Text>
            {hasData.region && (
              <Text size="sm">
                <strong>Location:</strong> {hasData.kebele}, {hasData.woreda},{" "}
                {hasData.zone}, {hasData.region}
              </Text>
            )}
          </Stack>
        </Alert>
      )}
    </Stack>
  );
}
