import {
  Alert,
  Button,
  Divider,
  Group,
  Loader,
  Select,
  SimpleGrid,
  Stack,
  Text,
  TextInput,
  Tooltip,
} from "@mantine/core";
import { zodResolver } from "@hookform/resolvers/zod";
import { useQuery } from "@tanstack/react-query";
import { AlertCircle, ArrowLeft, ArrowRight, Info } from "lucide-react";
import { useEffect, useMemo, useRef, useState } from "react";
import { Controller, useForm } from "react-hook-form";

import type { AuthUser } from "@/types/auth";
import type { CreateCompanyPayload } from "@/services/companies.service";
import type { ProfileResponse, UpdateProfilePayload } from "@/types/profile";
import type { CompanyRegistrationData } from "@edr/types";
import { ETHIOPIAN_REGIONS } from "@edr/types";
import { ControlledPhoneField, toEthiopianE164 } from "@/components/PhoneField";
import { SmartFileInput } from "@edr/ui-common";
import { getMinFiles } from "@/types/fileUploadSettings";
import { api } from "@/services/api";
import RoleLicenseStep, {
  type RoleLicenseProfile,
} from "@/components/onboarding/RoleLicenseStep";
import ETradeInfo from "@/components/onboarding/ETradeInfo";
import {
  buildOnboardingSchema,
  type CompanyStep,
  type FormData,
  hasPoaDetails,
  POA_DELEGATION_FILE_KEY,
  stepFields,
} from "./companyProfileForm/schema";
import {
  buildPayload,
  stepPayload,
  toFormValues,
} from "./companyProfileForm/helpers";
import { LinkCheckboxCard } from "./companyProfileForm/LinkCheckboxCard";
import { ReadOnlyField } from "./companyProfileForm/ReadOnlyField";

export default function CompanyProfileForm({
  documentSettingCode,
  documentFiles: controlledFiles,
  onDocumentFilesChange,
  user,
  onSubmit,
  isPending,
  onBack,
  initialStep,
  resyncOpen,
  onStepChange,
  onSaveStep,
  rehydrate,
  roleProfiles,
  licenseFiles,
  onLicenseChange,
  submitError,
  uploadedDocumentKeys,
  onUploadDocuments,
}: {
  documentSettingCode: string;
  documentFiles?: Record<string, File | File[] | null>;
  onDocumentFilesChange?: (files: Record<string, File | File[] | null>) => void;
  user: AuthUser;
  onSubmit: (data: CreateCompanyPayload) => void;
  isPending: boolean;
  onBack: () => void;
  /** Step to resume at (defaults to "company"). */
  initialStep?: CompanyStep;
  /** When this flips true (dialog reopened), jump back to initialStep (furthest reached). */
  resyncOpen?: boolean;
  /** Reports the active step so the parent can persist resume progress. */
  onStepChange?: (step: CompanyStep) => void;
  /** Persist the current step's data before advancing; returns an error to show. */
  onSaveStep?: (
    data: Partial<UpdateProfilePayload>,
  ) => Promise<{ ok: true } | { ok: false; error: string }>;
  /** Saved profile to seed the form with (rehydration after refresh). */
  rehydrate?: ProfileResponse | null;
  /** Operational profiles for the final per-role license step. */
  roleProfiles?: RoleLicenseProfile[];
  /** Newly-selected license files per profile id. */
  licenseFiles?: Record<string, File[]>;
  onLicenseChange?: (value: Record<string, File[]>) => void;
  /** Server error from the final submit (uploads/complete), shown verbatim. */
  submitError?: string | null;
  /** fileKeys whose company document is already uploaded server-side (resume). */
  uploadedDocumentKeys?: string[];
  /**
   * Auto-upload the currently-selected company documents (the Documents step's
   * "Continue" action). Resolves to an error message string on failure so the
   * step can surface it and hold the user in place.
   */
  onUploadDocuments?: () => Promise<
    { ok: true } | { ok: false; error: string }
  >;
}) {
  const [step, setStep] = useState<CompanyStep>(initialStep ?? "company");
  const [saving, setSaving] = useState(false);
  const [saveError, setSaveError] = useState<string | null>(null);

  // Report each step change up so the wizard can persist it for resume.
  useEffect(() => {
    onStepChange?.(step);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [step]);

  // Tracks whether the user has manually navigated the form this session. While
  // false, the form still follows the parent's resume target (initialStep) —
  // which can shift to an earlier step once server data lands (e.g. a required
  // document turns out to be un-uploaded, so we must not rest on a later step).
  const userNavigatedRef = useRef(false);

  // On reopen, jump to the furthest step reached (initialStep) so progress
  // never appears to reset. Re-arm the follow-the-parent behaviour too.
  const wasOpen = useRef(resyncOpen);
  useEffect(() => {
    if (resyncOpen && !wasOpen.current && initialStep) {
      userNavigatedRef.current = false;
      setStep(initialStep);
      setSaveError(null);
    }
    wasOpen.current = resyncOpen;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [resyncOpen]);

  // Follow a parent-driven resume correction: if initialStep changes (the wizard
  // re-clamps it back once onboarding requirements load — e.g. a required
  // document is still missing, so it must not skip ahead to Business License),
  // adopt it, but only while the user hasn't started navigating themselves.
  const lastInitialStep = useRef(initialStep);
  useEffect(() => {
    if (initialStep && initialStep !== lastInitialStep.current) {
      lastInitialStep.current = initialStep;
      if (!userNavigatedRef.current) {
        setStep(initialStep);
        setSaveError(null);
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [initialStep]);
  const [internalFiles, setInternalFiles] = useState<
    Record<string, File | File[] | null>
  >({});
  const documentFiles = controlledFiles ?? internalFiles;
  const setDocumentFiles = onDocumentFilesChange ?? setInternalFiles;

  const { data: uploadSetting, isLoading: loadingDocuments } = useQuery(
    api.fileUploadSettings.getByCode.queryOptions({
      input: { code: documentSettingCode },
      refetchOnMount: false,
    }),
  );

  // A freight forwarder signs on other companies' behalf, so its Power of
  // Attorney (details + delegation letter) is mandatory rather than optional.
  const requirePoa = (roleProfiles ?? []).some(
    (p) => p.type === "freight_forwarder",
  );

  const {
    register,
    control,
    handleSubmit,
    trigger,
    watch,
    setValue,
    formState: { errors },
  } = useForm<FormData>({
    resolver: zodResolver(buildOnboardingSchema(requirePoa)),
    defaultValues: {
      companyName: "",
      companyEmail: "",
      companyPhone: "",
      companyLocation: "",
      companyAddress: "",
      tinNumber: "",
      vatNumber: "",
      fanNumber: "",
      licenceNumber: "",
      statusDescription: "",
      dateRegistered: "",
      renewedFrom: "",
      renewalDate: "",
      renewedTo: "",
      region: "",
      zone: "",
      woreda: "",
      kebele: "",
      houseNo: "",
      contactPersonName: "",
      contactPersonPosition: "",
      contactPersonEmail: "",
      contactPersonPhone: "",
      generalManagerName: "",
      generalManagerEmail: "",
      generalManagerPhone: "",
      poaName: "",
      poaPhone: "",
      poaAddress: "",
      poaEmail: "",
      poaLocation: "",
    },
    // Rehydrate from previously-saved data (RHF re-syncs when `values` change).
    values: rehydrate ? toFormValues(rehydrate) : undefined,
  });

  // eTrade carries no email, so the company/contact email fields start blank.
  // Seed them from the registering user's account email — but only while empty,
  // so a typed or rehydrated value is never overwritten.
  useEffect(() => {
    if (!user?.email) return;
    if (!watch("companyEmail")) {
      setValue("companyEmail", user.email, { shouldValidate: true });
    }
    if (!watch("contactPersonEmail")) {
      setValue("contactPersonEmail", user.email);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [user?.email, rehydrate]);

  // Keep the (hidden, derived) company address in sync with the editable address
  // fields — so it reflects both the eTrade auto-fill and any later user edits,
  // instead of only whatever was composed at lookup time.
  const region = watch("region");
  const zone = watch("zone");
  const woreda = watch("woreda");
  const kebele = watch("kebele");
  const houseNo = watch("houseNo");
  useEffect(() => {
    const composed = [houseNo, kebele, woreda, zone, region]
      .filter((part) => part && part.trim())
      .join(", ");
    setValue("companyAddress", composed);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [region, zone, woreda, kebele, houseNo]);

  // The business owner/manager pulled from eTrade — powers "Use owner as
  // manager" on the General Manager step. Null until a TIN lookup succeeds.
  const [etradeOwner, setEtradeOwner] = useState<{
    name: string;
    phone: string;
  } | null>(null);

  const handleETradeDataLoaded = (data: CompanyRegistrationData) => {
    if (data.companyName) {
      setValue("companyName", data.companyName, { shouldValidate: true });
    }
    setValue("licenceNumber", data.licenceNumber);
    setValue("statusDescription", data.statusDescription);
    setValue("dateRegistered", data.dateRegistered);
    setValue("renewedFrom", data.renewedFrom);
    setValue("renewalDate", data.renewalDate);
    setValue("renewedTo", data.renewedTo);
    setValue("region", data.region);
    setValue("zone", data.zone);
    setValue("woreda", data.woreda);
    setValue("kebele", data.kebele);
    setValue("houseNo", data.houseNo);
    setValue(
      "companyPhone",
      toEthiopianE164(data.regularPhone || data.mobilePhone),
    );
    // companyAddress is composed reactively from the address fields below, so
    // setting region/zone/woreda/kebele/houseNo above is enough — no need to
    // compose it here.

    // Pre-fill the company contact phone from eTrade's mobile number.
    const mobile = toEthiopianE164(data.mobilePhone || data.regularPhone);
    if (mobile) {
      setValue("companyPhone", mobile, { shouldValidate: true });
    }

    setEtradeOwner({
      name: data.managerName,
      phone: toEthiopianE164(
        data.managerPhone || data.regularPhone || data.mobilePhone,
      ),
    });
  };

  // "Same as …" links. A checked card prefills the target step's fields from the
  // source step and disables them (kept mirrored while linked); unchecking clears
  // them and re-enables editing.
  const [gmSameAsOwner, setGmSameAsOwner] = useState(false);
  const [contactSameAsGm, setContactSameAsGm] = useState(false);
  const [poaSameAsContact, setPoaSameAsContact] = useState(false);

  // General Manager source. The company step's email/phone are seeded from
  // eTrade (and the account email) but stay editable, so the link reads the
  // CURRENT form values rather than the frozen eTrade snapshot — an edit on the
  // company step propagates here, the same way "Same as General Manager" tracks
  // the general manager's live values. eTrade's owner name has no editable
  // field of its own, so it falls back to the registering user's account name.
  const companyEmail = watch("companyEmail");
  const companyPhone = watch("companyPhone");
  const gmSourceName = etradeOwner?.name ?? user.name?.en ?? "";
  const gmSourceEmail = companyEmail || user.email || "";
  const gmSourcePhone =
    companyPhone || etradeOwner?.phone || toEthiopianE164(user.phoneNumber) || "";

  useEffect(() => {
    if (!gmSameAsOwner) return;
    setValue("generalManagerName", gmSourceName, { shouldValidate: true });
    setValue("generalManagerEmail", gmSourceEmail, { shouldValidate: true });
    setValue("generalManagerPhone", gmSourcePhone, {
      shouldValidate: true,
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [gmSameAsOwner, gmSourceName, gmSourceEmail, gmSourcePhone]);

  const toggleGmSameAsOwner = (checked: boolean) => {
    setGmSameAsOwner(checked);
    if (!checked) {
      setValue("generalManagerName", "");
      setValue("generalManagerEmail", "");
      setValue("generalManagerPhone", "");
    }
  };

  const gmName = watch("generalManagerName");
  const gmEmail = watch("generalManagerEmail");
  const gmPhone = watch("generalManagerPhone");
  const contactName = watch("contactPersonName");
  const contactEmail = watch("contactPersonEmail");
  const contactPhone = watch("contactPersonPhone");

  // While linked, mirror the source values into the (disabled) target fields so
  // the copy stays current even if the user goes back and edits the source.
  useEffect(() => {
    if (!contactSameAsGm) return;
    setValue("contactPersonName", gmName ?? "", { shouldValidate: true });
    setValue("contactPersonEmail", gmEmail ?? "");
    setValue("contactPersonPhone", gmPhone ?? "", { shouldValidate: true });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [contactSameAsGm, gmName, gmEmail, gmPhone]);

  // The contact-person step has no location/address of its own, so the linked
  // PoA takes the company's — location as entered, address as composed from the
  // company's address fields. Both stay mirrored while the link is checked.
  const companyLocation = watch("companyLocation");
  const companyAddress = watch("companyAddress");

  useEffect(() => {
    if (!poaSameAsContact) return;
    setValue("poaName", contactName ?? "");
    setValue("poaEmail", contactEmail ?? "");
    setValue("poaPhone", contactPhone ?? "");
    setValue("poaLocation", companyLocation ?? "");
    setValue("poaAddress", companyAddress ?? "");
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    poaSameAsContact,
    contactName,
    contactEmail,
    contactPhone,
    companyLocation,
    companyAddress,
  ]);

  const toggleContactSameAsGm = (checked: boolean) => {
    setContactSameAsGm(checked);
    // Checked → the mirror effect fills the fields; unchecked → reset them.
    if (!checked) {
      setValue("contactPersonName", "");
      setValue("contactPersonEmail", "");
      setValue("contactPersonPhone", "");
    }
  };

  const togglePoaSameAsContact = (checked: boolean) => {
    setPoaSameAsContact(checked);
    if (!checked) {
      setValue("poaName", "");
      setValue("poaEmail", "");
      setValue("poaPhone", "");
      setValue("poaLocation", "");
      setValue("poaAddress", "");
    }
  };

  // The delegation letter is seeded into the same nationality document set as
  // the rest, but belongs on the PoA step next to the details it evidences —
  // so it's split out here and the Documents step renders the remainder. Both
  // halves share `documentFiles`, so the existing bulk upload still carries it.
  const poaDocumentField = uploadSetting?.fields?.find(
    (f) => f.fileKey === POA_DELEGATION_FILE_KEY,
  );
  const documentsSetting = useMemo(
    () =>
      uploadSetting
        ? {
            ...uploadSetting,
            fields: uploadSetting.fields.filter(
              (f) => f.fileKey !== POA_DELEGATION_FILE_KEY,
            ),
          }
        : undefined,
    [uploadSetting],
  );
  const poaDocumentSetting = useMemo(
    () =>
      uploadSetting && poaDocumentField
        ? { ...uploadSetting, fields: [poaDocumentField] }
        : undefined,
    [uploadSetting, poaDocumentField],
  );

  const hasDocuments = Boolean(documentsSetting?.fields?.length);

  // Hard verification for the documents step: required company-level
  // documents and a business license per operational profile must both be
  // present before the user can continue.
  const [documentFieldErrors, setDocumentFieldErrors] = useState<
    Record<string, string>
  >({});
  const [licenseFieldErrors, setLicenseFieldErrors] = useState<
    Record<string, string>
  >({});

  const validateRequiredDocuments = (): Record<string, string> => {
    const errs: Record<string, string> = {};
    for (const field of documentsSetting?.fields ?? []) {
      const min = getMinFiles(field);
      if (min <= 0) continue;
      if ((uploadedDocumentKeys ?? []).includes(field.fileKey)) 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;
  };

  // Every role needs at least one license file (existing or newly selected).
  const validateLicenses = (): Record<string, string> => {
    const errs: Record<string, string> = {};
    for (const p of roleProfiles ?? []) {
      const hasNew = (licenseFiles?.[p.id]?.length ?? 0) > 0;
      const hasExisting = p.existingFiles.length > 0;
      if (!hasNew && !hasExisting) {
        errs[p.id] = "Business license is required";
      }
    }
    return errs;
  };

  const handleDocumentFilesChange = (
    next: Record<string, File | File[] | null>,
  ) => {
    setDocumentFiles(next);
    setDocumentFieldErrors((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;
    });
  };

  const handleLicenseFilesChange = (next: Record<string, File[]>) => {
    onLicenseChange?.(next);
    setLicenseFieldErrors((prev) => {
      if (Object.keys(prev).length === 0) return prev;
      const updated = { ...prev };
      for (const id of Object.keys(updated)) {
        if ((next[id]?.length ?? 0) > 0) delete updated[id];
      }
      return updated;
    });
  };

  // The registration/license details come straight from the eTrade lookup and
  // are not user-editable — shown as a read-only confirmation once a TIN lookup
  // (or rehydration) has filled them in. The address fields below are separate:
  // user-entered and required. We watch the values so the display stays current.
  const registration = watch([
    "licenceNumber",
    "statusDescription",
    "dateRegistered",
    "renewalDate",
    "renewedFrom",
    "renewedTo",
  ]);
  const hasRegistrationDetails = registration.some((v) => v && v.trim());

  // Single source of truth for step sequence — navigation, labels and the
  // progress bar all derive from this so adding/removing a step is one edit.
  const stepOrder: CompanyStep[] = [
    "company",
    "personnel",
    "contact",
    "poa",
    "documents",
  ];
  const currentIdx = stepOrder.indexOf(step);

  // The delegation letter is what proves the representative was actually
  // delegated, so it's required the moment a PoA exists — and unconditionally
  // for a freight forwarder, whose PoA itself is mandatory. Skipped entirely
  // when the document set predates the field (seeder not yet re-run).
  const poaProvided = hasPoaDetails(watch());
  const delegationRequired =
    Boolean(poaDocumentField) && (requirePoa || poaProvided);
  const delegationPresent =
    (uploadedDocumentKeys ?? []).includes(POA_DELEGATION_FILE_KEY) ||
    (() => {
      const v = documentFiles[POA_DELEGATION_FILE_KEY];
      return Array.isArray(v) ? v.length > 0 : v != null;
    })();

  /** Validate + persist the current step, returning whether we may advance. */
  const saveCurrentStep = async (): Promise<boolean> => {
    setSaveError(null);
    const isValid = await trigger(stepFields[step]);
    if (!isValid) return false;
    if (!onSaveStep) return true;
    setSaving(true);
    try {
      const res = await onSaveStep(stepPayload(step, watch()));
      if (!res.ok) {
        setSaveError(res.error);
        return false;
      }
      return true;
    } finally {
      setSaving(false);
    }
  };

  const nextStep = async () => {
    userNavigatedRef.current = true;
    // The documents step hard-blocks on required company documents and a
    // business license per operational profile before it auto-uploads and
    // submits — no partial-completion path forward.
    if (step === "documents") {
      const docErrors = validateRequiredDocuments();
      const licenseErrors = validateLicenses();
      if (Object.keys(docErrors).length > 0 || Object.keys(licenseErrors).length > 0) {
        setDocumentFieldErrors(docErrors);
        setLicenseFieldErrors(licenseErrors);
        setSaveError("Please upload all required documents before continuing.");
        return;
      }

      if (onUploadDocuments) {
        setSaving(true);
        try {
          const res = await onUploadDocuments();
          if (!res.ok) {
            setSaveError(res.error);
            return;
          }
        } finally {
          setSaving(false);
        }
      }

      setSaveError(null);
      handleSubmit((data) => onSubmit(buildPayload(data, user)))();
      return;
    }
    // The PoA step also gates on a file, which lives outside the form state.
    if (step === "poa" && delegationRequired && !delegationPresent) {
      setDocumentFieldErrors({
        [POA_DELEGATION_FILE_KEY]: "Delegation letter is required",
      });
      setSaveError(
        requirePoa
          ? "Freight forwarders must provide Power of Attorney details and a delegation letter."
          : "Upload the delegation letter for the Power of Attorney you entered, or clear the PoA details to skip.",
      );
      // Fall through to validate the text fields too, so every problem shows at once.
      await trigger(stepFields.poa);
      return;
    }
    // Field steps validate + save before advancing.
    const ok = await saveCurrentStep();
    if (!ok) return;
    setStep(stepOrder[currentIdx + 1]);
  };

  const prevStep = () => {
    userNavigatedRef.current = true;
    setSaveError(null);
    if (currentIdx === 0) onBack();
    else setStep(stepOrder[currentIdx - 1]);
  };

  return (
    <>
      <form onSubmit={(e) => e.preventDefault()}>
        <Stack gap="md">
          {step === "company" && (
            <Stack gap="sm">
              <ETradeInfo
                tin={watch("tinNumber")}
                register={register("tinNumber")}
                error={errors.tinNumber?.message}
                onDataLoaded={handleETradeDataLoaded}
              />

              <TextInput
                label="Company Name"
                placeholder="Global Logistics Ltd"
                error={errors.companyName?.message}
                {...register("companyName")}
              />
              <SimpleGrid cols={2} spacing="md">
                <TextInput
                  label="Company Email"
                  type="email"
                  placeholder="ops@company.com"
                  error={errors.companyEmail?.message}
                  {...register("companyEmail")}
                />
                <ControlledPhoneField
                  control={control}
                  name="companyPhone"
                  label="Company Phone"
                  required
                />
              </SimpleGrid>
              <TextInput
                label="Location"
                placeholder="Addis Ababa, Ethiopia"
                error={errors.companyLocation?.message}
                {...register("companyLocation")}
              />
              <SimpleGrid cols={2} spacing="md">
                <TextInput
                  label="VAT Number"
                  placeholder="VAT-12345"
                  maxLength={10}
                  error={errors.vatNumber?.message}
                  {...register("vatNumber")}
                />
                <TextInput
                  label={
                    <Group gap={6} align="center" wrap="nowrap">
                      <span>FAN Number (16 digits)</span>
                      <Tooltip
                        label="The FAN must belong to the person with power of attorney. If the company has no power of attorney, use the general manager's FAN."
                        multiline
                        w={260}
                        withArrow
                        position="top-start"
                      >
                        <Info
                          size={14}
                          color="var(--mantine-color-gray-6)"
                          className="cursor-help"
                        />
                      </Tooltip>
                    </Group>
                  }
                  placeholder="1234567890123456"
                  maxLength={16}
                  error={errors.fanNumber?.message}
                  {...register("fanNumber")}
                />
              </SimpleGrid>

              {hasRegistrationDetails && (
                <>
                  <Divider my="sm" />
                  <Group gap="xs" align="center">
                    <Text fw={600} size="sm" c="edr-text">
                      Registration Details
                    </Text>
                    <Text size="xs" c="dimmed">
                      from eTrade · read-only
                    </Text>
                  </Group>
                  <SimpleGrid cols={2} spacing="sm">
                    <ReadOnlyField
                      label="License Number"
                      value={watch("licenceNumber")}
                    />
                    <ReadOnlyField
                      label="Status"
                      value={watch("statusDescription")}
                    />
                    <ReadOnlyField
                      label="Date Registered"
                      value={watch("dateRegistered")}
                    />
                    <ReadOnlyField
                      label="Renewal Date"
                      value={watch("renewalDate")}
                    />
                    <ReadOnlyField
                      label="Renewed From"
                      value={watch("renewedFrom")}
                    />
                    <ReadOnlyField
                      label="Renewed To"
                      value={watch("renewedTo")}
                    />
                  </SimpleGrid>
                </>
              )}

              <Divider my="sm" />
              <Text fw={600} size="sm" c="edr-text">
                Address Information
              </Text>
              <SimpleGrid cols={2} spacing="md">
                <Controller
                  name="region"
                  control={control}
                  render={({ field }) => (
                    <Select
                      label="Region"
                      placeholder="Select region"
                      required
                      searchable
                      data={ETHIOPIAN_REGIONS.map((r) => ({ value: r, label: r }))}
                      error={errors.region?.message}
                      // "" (unresolved eTrade value, or a legacy row whose
                      // region isn't in the list) must read as "nothing picked".
                      value={field.value || null}
                      onChange={(v) => field.onChange(v ?? "")}
                      onBlur={field.onBlur}
                    />
                  )}
                />
                <TextInput
                  label="Zone"
                  placeholder="EASTERN TIGRAY"
                  required
                  error={errors.zone?.message}
                  {...register("zone")}
                />
              </SimpleGrid>
              <SimpleGrid cols={2} spacing="md">
                <TextInput
                  label="Woreda"
                  placeholder="EROB"
                  required
                  error={errors.woreda?.message}
                  {...register("woreda")}
                />
                <TextInput
                  label="Kebele"
                  placeholder="ARAS"
                  required
                  error={errors.kebele?.message}
                  {...register("kebele")}
                />
              </SimpleGrid>
              <SimpleGrid cols={2} spacing="md">
                <TextInput
                  label="House No"
                  placeholder="House Number"
                  required
                  error={errors.houseNo?.message}
                  {...register("houseNo")}
                />
              </SimpleGrid>
            </Stack>
          )}

          {step === "personnel" && (
            <>
              <Text fw={600} size="sm" c="edr-text">
                General Manager
              </Text>
              <LinkCheckboxCard
                checked={gmSameAsOwner}
                onToggle={toggleGmSameAsOwner}
                title="Same as business owner"
                description={
                  etradeOwner
                    ? "Reuse the eTrade-registered owner's name, plus the company email and phone as you entered them. Uncheck to enter different details."
                    : "Reuse your account's name and the company email and phone as you entered them. Uncheck to enter different details."
                }
              />
              <TextInput
                label="Name"
                placeholder="Abebe Bikila"
                error={errors.generalManagerName?.message}
                {...register("generalManagerName")}
              />
              <SimpleGrid cols={2} spacing="md">
                <TextInput
                  label="Email"
                  type="email"
                  placeholder="gm@company.com"
                  error={errors.generalManagerEmail?.message}
                  {...register("generalManagerEmail")}
                />
                <ControlledPhoneField
                  control={control}
                  name="generalManagerPhone"
                  label="Phone"
                  required
                />
              </SimpleGrid>
            </>
          )}

          {step === "contact" && (
            <>
              <Text fw={600} size="sm" c="edr-text">
                Contact Person
              </Text>
              {watch("generalManagerName") && (
                <LinkCheckboxCard
                  checked={contactSameAsGm}
                  onToggle={toggleContactSameAsGm}
                  title="Same as General Manager"
                  description="Reuse the general manager's name, email and phone. Uncheck to enter different details."
                />
              )}
              <SimpleGrid cols={2} spacing="md">
                <TextInput
                  label="Name"
                  placeholder="Jane Smith"
                  error={errors.contactPersonName?.message}
                  {...register("contactPersonName")}
                />
                <TextInput
                  label="Position (Optional)"
                  placeholder="Operations Lead"
                  error={errors.contactPersonPosition?.message}
                  {...register("contactPersonPosition")}
                />
              </SimpleGrid>
              <SimpleGrid cols={2} spacing="md">
                <TextInput
                  label="Email (Optional)"
                  type="email"
                  placeholder="contact@company.com"
                  error={errors.contactPersonEmail?.message}
                  {...register("contactPersonEmail")}
                />
                <ControlledPhoneField
                  control={control}
                  name="contactPersonPhone"
                  label="Phone"
                  required
                />
              </SimpleGrid>
            </>
          )}

          {step === "poa" && (
            <>
              <Text size="sm" c="edr-muted">
                {requirePoa
                  ? "As a freight forwarder you act on other companies' behalf, so Power of Attorney details and a delegation letter are required."
                  : "Power of Attorney details are optional. Fill them in if you have them, or skip to continue. If you do enter a representative, upload the delegation letter authorising them."}
              </Text>
              {watch("contactPersonName") && (
                <LinkCheckboxCard
                  checked={poaSameAsContact}
                  onToggle={togglePoaSameAsContact}
                  title="Same as contact person"
                  description="Reuse the contact person's name, email and phone, plus the company's location and address. Uncheck to enter different details."
                />
              )}
              <TextInput
                label="PoA Name"
                placeholder="Authorized Representative Name"
                error={errors.poaName?.message}
                {...register("poaName")}
              />
              <SimpleGrid cols={2} spacing="md">
                <TextInput
                  label="PoA Email"
                  type="email"
                  placeholder="poa@company.com"
                  error={errors.poaEmail?.message}
                  {...register("poaEmail")}
                />
                <ControlledPhoneField
                  control={control}
                  name="poaPhone"
                  label="PoA Phone"
                />
              </SimpleGrid>
              <SimpleGrid cols={2} spacing="md">
                <TextInput
                  label="PoA Location"
                  placeholder="City, Country"
                  error={errors.poaLocation?.message}
                  {...register("poaLocation")}
                />
                <TextInput
                  label="PoA Address"
                  placeholder="Full Address"
                  error={errors.poaAddress?.message}
                  {...register("poaAddress")}
                />
              </SimpleGrid>

              {poaDocumentSetting && (
                <>
                  <Divider my="sm" />
                  <SmartFileInput
                    file={poaDocumentSetting}
                    value={documentFiles}
                    uploadedKeys={uploadedDocumentKeys}
                    errors={documentFieldErrors}
                    onChange={handleDocumentFilesChange}
                  />
                </>
              )}
            </>
          )}

          {step === "documents" && (
            <>
              {loadingDocuments ? (
                <Group justify="center" py="xl">
                  <Loader size="sm" color="edr-green" />
                </Group>
              ) : !documentsSetting ? (
                <Text size="sm" c="edr-muted" ta="center" py="md">
                  No document requirements found for your account type.
                </Text>
              ) : (
                <SmartFileInput
                  file={documentsSetting}
                  value={documentFiles}
                  uploadedKeys={uploadedDocumentKeys}
                  errors={documentFieldErrors}
                  containerClassName="lg:grid grid-cols-2 items-stretch"
                  onChange={handleDocumentFilesChange}
                />
              )}

              <RoleLicenseStep
                profiles={roleProfiles ?? []}
                value={licenseFiles ?? {}}
                onChange={handleLicenseFilesChange}
                errors={licenseFieldErrors}
              />
            </>
          )}

          {saveError && (
            <Alert
              color="red"
              variant="light"
              icon={<AlertCircle size={18} />}
              title={"Couldn't save this step"}
            >
              {saveError}
            </Alert>
          )}

          {submitError && (
            <Alert
              color="red"
              variant="light"
              icon={<AlertCircle size={18} />}
              title="Couldn't submit your application"
            >
              {submitError}
            </Alert>
          )}

          <Group justify="space-between" pt="xs">
            <Button
              variant="default"
              onClick={prevStep}
              leftSection={<ArrowLeft size={16} />}
            >
              Back
            </Button>
            <Button
              color="edr-green"
              onClick={nextStep}
              disabled={
                isPending ||
                saving ||
                (step === "documents" && !hasDocuments && loadingDocuments)
              }
              loading={isPending || saving}
              rightSection={
                !isPending && !saving ? <ArrowRight size={16} /> : undefined
              }
            >
              {step === "documents" ? "Submit for review" : "Continue"}
            </Button>
          </Group>
        </Stack>
      </form>
    </>
  );
}
