import { useState } from "react";
import { useForm } from "react-hook-form";
import { useQuery } from "@tanstack/react-query";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import {
  ArrowRight,
  ArrowLeft,
  Building2,
  User,
  FileText,
  CheckCircle2,
  Loader2,
  ChevronLeft,
  UploadCloud,
} from "lucide-react";
import type { AuthUser } from "@/types/auth";
import type { CreateCompanyPayload } from "@/services/companies.service";
import PhoneInput from "@/components/auth/PhoneInput";
import {
  Button,
  Input,
  Field,
  FieldLabel,
  FieldError,
  FieldGroup,
  SmartFileInput,
} from "@edr/ui-common";
import { api } from "@/services/api";

type CompanyStep = "company" | "personnel" | "poa" | "documents" | "confirm";

const onboardingSchema = z.object({
  companyName: z.string().min(1, "Company name is required"),
  companyEmail: z.string().email("Invalid email address"),
  companyPhone: z.string().min(1, "Company phone is required"),
  companyPhoneCountryCode: z.string().min(1, "Country code is required"),
  companyLocation: z.string().min(1, "Location is required"),
  companyAddress: z.string().min(1, "Address is required"),
  tinNumber: z.string().length(10, "TIN must be exactly 10 digits"),
  vatNumber: z
    .string()
    .min(1, "VAT number is required")
    .length(10, "VAT number must be exactly 10 digits"),
  fanNumber: z.string().length(16, "FAN must be exactly 16 digits"),
  contactPersonName: z.string().min(1, "Contact person name is required"),
  contactPersonPhone: z.string().min(1, "Contact person phone is required"),
  contactPersonPhoneCountryCode: z.string().min(1, "Country code is required"),
  generalManagerName: z.string().min(1, "GM name is required"),
  generalManagerEmail: z.string().email("Invalid GM email"),
  generalManagerPhone: z.string().min(1, "GM phone is required"),
  generalManagerPhoneCountryCode: z.string().min(1, "Country code is required"),
  poaName: z.string().optional(),
  poaPhone: z.string().optional(),
  poaPhoneCountryCode: z.string().optional(),
  poaAddress: z.string().optional(),
  poaEmail: z.string().optional(),
  poaLocation: z.string().optional(),
});

type FormData = z.infer<typeof onboardingSchema>;

const stepFields: Record<CompanyStep, (keyof FormData)[]> = {
  company: [
    "companyName",
    "companyEmail",
    "companyPhone",
    "companyPhoneCountryCode",
    "companyLocation",
    "companyAddress",
    "tinNumber",
    "vatNumber",
    "fanNumber",
  ],
  personnel: [
    "contactPersonName",
    "contactPersonPhone",
    "contactPersonPhoneCountryCode",
    "generalManagerName",
    "generalManagerEmail",
    "generalManagerPhone",
    "generalManagerPhoneCountryCode",
  ],
  poa: [],
  documents: [],
  confirm: [],
};

function buildPayload(data: FormData, _user: AuthUser): CreateCompanyPayload {
  return {
    companyName: data.companyName,
    companyEmail: data.companyEmail,
    companyPhone: `${data.companyPhoneCountryCode}${data.companyPhone}`,
    companyLocation: data.companyLocation,
    companyAddress: data.companyAddress,
    tin: data.tinNumber,
    vatNumber: data.vatNumber,
    fanNumber: data.fanNumber,
    attributes: {
      contactPersonName: data.contactPersonName,
      contactPersonPhone: `${data.contactPersonPhoneCountryCode}${data.contactPersonPhone}`,
      generalManagerName: data.generalManagerName,
      generalManagerEmail: data.generalManagerEmail,
      generalManagerPhone: `${data.generalManagerPhoneCountryCode}${data.generalManagerPhone}`,
      poaName: data.poaName || undefined,
      poaPhone:
        data.poaPhone && data.poaPhoneCountryCode
          ? `${data.poaPhoneCountryCode}${data.poaPhone}`
          : undefined,
      poaAddress: data.poaAddress || undefined,
      poaEmail: data.poaEmail || undefined,
      poaLocation: data.poaLocation || undefined,
    },
  };
}

export default function CompanyProfileForm({
  documentSettingCode,
  documentFiles: controlledFiles,
  onDocumentFilesChange,
  user,
  onSubmit,
  isPending,
  onBack,
}: {
  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;
}) {
  const [step, setStep] = useState<CompanyStep>("company");
  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,
    }),
  );

  const {
    register,
    handleSubmit,
    trigger,
    watch,
    formState: { errors },
  } = useForm<FormData>({
    resolver: zodResolver(onboardingSchema),
    defaultValues: {
      companyName: "",
      companyEmail: "",
      companyPhone: "",
      companyPhoneCountryCode: "+251",
      companyLocation: "",
      companyAddress: "",
      tinNumber: "",
      vatNumber: "",
      fanNumber: "",
      contactPersonName: "",
      contactPersonPhone: "",
      contactPersonPhoneCountryCode: "+251",
      generalManagerName: "",
      generalManagerEmail: "",
      generalManagerPhone: "",
      generalManagerPhoneCountryCode: "+251",
      poaName: "",
      poaPhone: "",
      poaPhoneCountryCode: "+251",
      poaAddress: "",
      poaEmail: "",
      poaLocation: "",
    },
  });

  const formValues = watch();
  const hasDocuments = Boolean(uploadSetting?.fields?.length);
  const totalSteps = 5;

  const nextStep = async () => {
    if (step === "poa") {
      setStep("documents");
      return;
    }
    if (step === "documents") {
      setStep("confirm");
      return;
    }
    if (step === "confirm") {
      handleSubmit((data) => onSubmit(buildPayload(data, user)))();
      return;
    }
    const fields = stepFields[step];
    const isValid = await trigger(fields);
    if (!isValid) return;
    setStep(step === "company" ? "personnel" : "poa");
  };

  const prevStep = () => {
    if (step === "company") {
      onBack();
    } else if (step === "personnel") {
      setStep("company");
    } else if (step === "poa") {
      setStep("personnel");
    } else if (step === "documents") {
      setStep("poa");
    } else {
      setStep("documents");
    }
  };

  return (
    <>
      <div className="mb-8">
        <button
          type="button"
          onClick={prevStep}
          className="mb-4 flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground transition-colors"
        >
          <ChevronLeft className="size-4" />
          Change account type
        </button>

        <div className="flex items-center justify-between max-w-lg mx-auto relative px-2">
          <div className="absolute top-1/2 left-0 w-full h-0.5 bg-border -translate-y-1/2 z-0" />
          <StepIcon
            icon={<Building2 className="size-5" />}
            active={step === "company"}
            completed={step !== "company"}
          />
          <StepIcon
            icon={<User className="size-5" />}
            active={step === "personnel"}
            completed={
              step === "poa" || step === "documents" || step === "confirm"
            }
          />
          <StepIcon
            icon={<FileText className="size-5" />}
            active={step === "poa"}
            completed={step === "documents" || step === "confirm"}
          />
          <StepIcon
            icon={<UploadCloud className="size-5" />}
            active={step === "documents"}
            completed={step === "confirm"}
          />
          <StepIcon
            icon={<CheckCircle2 className="size-5" />}
            active={step === "confirm"}
            completed={false}
          />
        </div>
        <p className="text-center text-sm text-muted-foreground mt-3">
          {step === "company" &&
            `Step 1 of ${totalSteps} — Company Information`}
          {step === "personnel" &&
            `Step 2 of ${totalSteps} — Personnel Details`}
          {step === "poa" &&
            `Step 3 of ${totalSteps} — Power of Attorney (Optional)`}
          {step === "documents" &&
            `Step 4 of ${totalSteps} — Upload Documents (Optional)`}
          {step === "confirm" && `Step 5 of ${totalSteps} — Review & Confirm`}
        </p>
      </div>

      <form
        onSubmit={(e) => e.preventDefault()}
        className="flex flex-col gap-4"
      >
        <FieldGroup className="gap-4">
          {step === "company" && (
            <>
              <Field data-invalid={Boolean(errors.companyName)}>
                <FieldLabel>Company Name</FieldLabel>
                <Input
                  placeholder="Global Logistics Ltd"
                  aria-invalid={Boolean(errors.companyName)}
                  {...register("companyName")}
                />
                <FieldError errors={[errors.companyName]} />
              </Field>

              <div className="grid grid-cols-2 gap-4">
                <Field data-invalid={Boolean(errors.companyEmail)}>
                  <FieldLabel>Company Email</FieldLabel>
                  <Input
                    type="email"
                    placeholder="ops@company.com"
                    aria-invalid={Boolean(errors.companyEmail)}
                    {...register("companyEmail")}
                  />
                  <FieldError errors={[errors.companyEmail]} />
                </Field>

                <PhoneInput
                  countryCode={{ ...register("companyPhoneCountryCode") }}
                  phone={{
                    ...register("companyPhone"),
                    placeholder: "912345678",
                  }}
                  countryCodeError={errors.companyPhoneCountryCode}
                  phoneError={errors.companyPhone}
                  label="Company Phone"
                />
              </div>

              <div className="grid grid-cols-2 gap-4">
                <Field data-invalid={Boolean(errors.companyLocation)}>
                  <FieldLabel>Location</FieldLabel>
                  <Input
                    placeholder="Addis Ababa, Ethiopia"
                    aria-invalid={Boolean(errors.companyLocation)}
                    {...register("companyLocation")}
                  />
                  <FieldError errors={[errors.companyLocation]} />
                </Field>

                <Field data-invalid={Boolean(errors.companyAddress)}>
                  <FieldLabel>Address</FieldLabel>
                  <Input
                    placeholder="Bole Subcity, Woreda 03"
                    aria-invalid={Boolean(errors.companyAddress)}
                    {...register("companyAddress")}
                  />
                  <FieldError errors={[errors.companyAddress]} />
                </Field>
              </div>

              <div className="grid grid-cols-2 gap-4">
                <Field data-invalid={Boolean(errors.tinNumber)}>
                  <FieldLabel>TIN Number (10 digits)</FieldLabel>
                  <Input
                    placeholder="1234567890"
                    maxLength={10}
                    aria-invalid={Boolean(errors.tinNumber)}
                    {...register("tinNumber")}
                  />
                  <FieldError errors={[errors.tinNumber]} />
                </Field>

                <Field data-invalid={Boolean(errors.vatNumber)}>
                  <FieldLabel>VAT Number</FieldLabel>
                  <Input
                    placeholder="VAT-12345"
                    aria-invalid={Boolean(errors.vatNumber)}
                    maxLength={10}
                    {...register("vatNumber")}
                  />
                  <FieldError errors={[errors.vatNumber]} />
                </Field>
              </div>

              <Field data-invalid={Boolean(errors.fanNumber)}>
                <FieldLabel>FAN Number (16 digits)</FieldLabel>
                <Input
                  placeholder="1234567890123456"
                  maxLength={16}
                  aria-invalid={Boolean(errors.fanNumber)}
                  {...register("fanNumber")}
                />
                <FieldError errors={[errors.fanNumber]} />
              </Field>
            </>
          )}

          {step === "personnel" && (
            <>
              <div>
                <h3 className="text-sm font-semibold text-foreground mb-3">
                  Contact Person
                </h3>
                <div className="grid grid-cols-2 gap-4">
                  <Field data-invalid={Boolean(errors.contactPersonName)}>
                    <FieldLabel>Name</FieldLabel>
                    <Input
                      placeholder="Jane Smith"
                      aria-invalid={Boolean(errors.contactPersonName)}
                      {...register("contactPersonName")}
                    />
                    <FieldError errors={[errors.contactPersonName]} />
                  </Field>

                  <PhoneInput
                    countryCode={{
                      ...register("contactPersonPhoneCountryCode"),
                    }}
                    phone={{
                      ...register("contactPersonPhone"),
                      placeholder: "912345678",
                    }}
                    countryCodeError={errors.contactPersonPhoneCountryCode}
                    phoneError={errors.contactPersonPhone}
                    label="Phone"
                  />
                </div>
              </div>

              <hr className="border-border" />

              <div>
                <h3 className="text-sm font-semibold text-foreground mb-3">
                  General Manager
                </h3>
                <div className="grid grid-cols-2 gap-4">
                  <Field
                    className="col-span-2"
                    data-invalid={Boolean(errors.generalManagerName)}
                  >
                    <FieldLabel>Name</FieldLabel>
                    <Input
                      placeholder="Abebe Bikila"
                      aria-invalid={Boolean(errors.generalManagerName)}
                      {...register("generalManagerName")}
                    />
                    <FieldError errors={[errors.generalManagerName]} />
                  </Field>

                  <Field data-invalid={Boolean(errors.generalManagerEmail)}>
                    <FieldLabel>Email</FieldLabel>
                    <Input
                      type="email"
                      placeholder="gm@company.com"
                      aria-invalid={Boolean(errors.generalManagerEmail)}
                      {...register("generalManagerEmail")}
                    />
                    <FieldError errors={[errors.generalManagerEmail]} />
                  </Field>

                  <PhoneInput
                    countryCode={{
                      ...register("generalManagerPhoneCountryCode"),
                    }}
                    phone={{
                      ...register("generalManagerPhone"),
                      placeholder: "912345678",
                    }}
                    countryCodeError={errors.generalManagerPhoneCountryCode}
                    phoneError={errors.generalManagerPhone}
                    label="Phone"
                  />
                </div>
              </div>
            </>
          )}

          {step === "poa" && (
            <>
              <p className="text-sm text-muted-foreground">
                Power of Attorney details are optional. Fill them in if you have
                them, or skip to continue.
              </p>

              <Field data-invalid={Boolean(errors.poaName)}>
                <FieldLabel>PoA Name</FieldLabel>
                <Input
                  placeholder="Authorized Representative Name"
                  aria-invalid={Boolean(errors.poaName)}
                  {...register("poaName")}
                />
                <FieldError errors={[errors.poaName]} />
              </Field>

              <div className="grid grid-cols-2 gap-4">
                <Field data-invalid={Boolean(errors.poaEmail)}>
                  <FieldLabel>PoA Email</FieldLabel>
                  <Input
                    type="email"
                    placeholder="poa@company.com"
                    aria-invalid={Boolean(errors.poaEmail)}
                    {...register("poaEmail")}
                  />
                  <FieldError errors={[errors.poaEmail]} />
                </Field>

                <PhoneInput
                  countryCode={{ ...register("poaPhoneCountryCode") }}
                  phone={{ ...register("poaPhone"), placeholder: "912345678" }}
                  label="PoA Phone"
                  countryCodeError={errors.poaPhoneCountryCode}
                  phoneError={errors.poaPhone}
                />
              </div>

              <div className="grid grid-cols-2 gap-4">
                <Field data-invalid={Boolean(errors.poaLocation)}>
                  <FieldLabel>PoA Location</FieldLabel>
                  <Input
                    placeholder="City, Country"
                    aria-invalid={Boolean(errors.poaLocation)}
                    {...register("poaLocation")}
                  />
                  <FieldError errors={[errors.poaLocation]} />
                </Field>

                <Field data-invalid={Boolean(errors.poaAddress)}>
                  <FieldLabel>PoA Address</FieldLabel>
                  <Input
                    placeholder="Full Address"
                    aria-invalid={Boolean(errors.poaAddress)}
                    {...register("poaAddress")}
                  />
                  <FieldError errors={[errors.poaAddress]} />
                </Field>
              </div>
            </>
          )}

          {step === "documents" && (
            <>
              {loadingDocuments ? (
                <div className="flex items-center justify-center py-8">
                  <Loader2 className="size-6 animate-spin text-muted-foreground" />
                </div>
              ) : !uploadSetting ? (
                <p className="text-sm text-muted-foreground text-center py-4">
                  No document requirements found for your account type.
                </p>
              ) : (
                <div className="flex flex-col gap-6">
                  <SmartFileInput
                    file={uploadSetting}
                    value={documentFiles}
                    onChange={setDocumentFiles}
                  />
                </div>
              )}
            </>
          )}

          {step === "confirm" && (
            <div className="space-y-4 rounded-xl border border-border bg-card p-4">
              <div>
                <h3 className="text-base font-semibold text-foreground">
                  Review your registration
                </h3>
                <p className="text-sm text-muted-foreground mt-1">
                  Confirm the company details below before saving.
                </p>
              </div>

              <div className="grid gap-3 md:grid-cols-2">
                <ReviewRow
                  label="Company name"
                  value={formValues.companyName}
                />
                <ReviewRow
                  label="Company email"
                  value={formValues.companyEmail}
                />
                <ReviewRow
                  label="Company phone"
                  value={formValues.companyPhone}
                />
                <ReviewRow
                  label="Location"
                  value={formValues.companyLocation}
                />
                <ReviewRow label="Address" value={formValues.companyAddress} />
                <ReviewRow label="TIN" value={formValues.tinNumber} />
                <ReviewRow label="VAT" value={formValues.vatNumber} />
                <ReviewRow label="FAN" value={formValues.fanNumber} />
                <ReviewRow
                  label="Contact person"
                  value={formValues.contactPersonName}
                />
                <ReviewRow
                  label="Contact phone"
                  value={`${formValues.contactPersonPhoneCountryCode}${formValues.contactPersonPhone}`}
                />
                <ReviewRow
                  label="General manager"
                  value={formValues.generalManagerName}
                />
                <ReviewRow
                  label="GM email"
                  value={formValues.generalManagerEmail}
                />
                <ReviewRow
                  label="GM phone"
                  value={`${formValues.generalManagerPhoneCountryCode}${formValues.generalManagerPhone}`}
                />
                <ReviewRow
                  label="PoA name"
                  value={formValues.poaName || undefined}
                />
                <ReviewRow
                  label="PoA phone"
                  value={
                    formValues.poaPhone && formValues.poaPhoneCountryCode
                      ? `${formValues.poaPhoneCountryCode}${formValues.poaPhone}`
                      : undefined
                  }
                />
                <ReviewRow
                  label="PoA email"
                  value={formValues.poaEmail || undefined}
                />
                <ReviewRow
                  label="PoA location"
                  value={formValues.poaLocation || undefined}
                />
              </div>
            </div>
          )}
        </FieldGroup>

        <div className="flex items-center justify-between pt-2">
          <Button type="button" variant="outline" onClick={prevStep}>
            <ArrowLeft />
            {step === "company"
              ? "Change Type"
              : step === "confirm"
                ? "Back to Documents"
                : "Back"}
          </Button>

          <div className="flex items-center gap-3">
            <Button
              type="button"
              onClick={step === "confirm" ? handleSubmit((data) => onSubmit(buildPayload(data, user))) : nextStep}
              disabled={isPending || (step === "documents" && !hasDocuments && loadingDocuments)}
            >
              {isPending ? (
                <>
                  <Loader2 className="animate-spin" />
                  Submitting...
                </>
              ) : step === "documents" ? (
                "Continue"
              ) : step === "confirm" ? (
                "Submit Registration"
              ) : (
                <>
                  Next Step
                  <ArrowRight />
                </>
              )}
            </Button>
          </div>
        </div>
      </form>
    </>
  );
}

function ReviewRow({ label, value }: { label: string; value?: string | null }) {
  return (
    <div className="rounded-lg border border-border bg-muted/20 p-3">
      <div className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
        {label}
      </div>
      <div className="mt-1 text-sm font-medium text-foreground">
        {value?.trim() ? value : "Not provided"}
      </div>
    </div>
  );
}

function StepIcon({
  icon,
  active,
  completed,
}: {
  icon: React.ReactNode;
  active: boolean;
  completed: boolean;
}) {
  return (
    <div
      className={`relative z-10 flex h-10 w-10 items-center justify-center rounded-full border-2 transition-all ${completed
          ? "bg-primary border-primary text-primary-foreground"
          : active
            ? "bg-background border-primary text-primary shadow-md"
            : "bg-background border-border text-muted-foreground"
        }`}
    >
      {completed ? <CheckCircle2 className="size-5" /> : icon}
    </div>
  );
}
