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,
  UserRound,
  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 DjiboutiStep = "company" | "representative" | "documents" | "confirm";

const djiboutiSchema = 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 / Country is required"),
  companyAddress: z.string().min(1, "Address is required"),
  repName: z.string().min(1, "Representative name is required"),
  repEmail: z.string().email("Invalid representative email"),
  repPhone: z.string().min(1, "Representative phone is required"),
  repPhoneCountryCode: z.string().min(1, "Country code is required"),
});

type FormData = z.infer<typeof djiboutiSchema>;

const stepFields: Record<DjiboutiStep, (keyof FormData)[]> = {
  company: [
    "companyName",
    "companyEmail",
    "companyPhone",
    "companyPhoneCountryCode",
    "companyLocation",
    "companyAddress",
  ],
  representative: [
    "repName",
    "repEmail",
    "repPhone",
    "repPhoneCountryCode",
  ],
  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: "",
    vatNumber: "",
    fanNumber: "",
    attributes: {
      repName: data.repName,
      repEmail: data.repEmail,
      repPhone: `${data.repPhoneCountryCode}${data.repPhone}`,
    },
  };
}

export default function DjiboutiAgentForm({
  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<DjiboutiStep>("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(djiboutiSchema),
    defaultValues: {
      companyName: "",
      companyEmail: "",
      companyPhone: "",
      companyPhoneCountryCode: "+253",
      companyLocation: "",
      companyAddress: "",
      repName: "",
      repEmail: "",
      repPhone: "",
      repPhoneCountryCode: "+253",
    },
  });

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

  const nextStep = async () => {
    if (step === "representative") {
      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("representative");
  };

  const skipDocuments = () => {
    setStep("confirm");
  };

  const prevStep = () => {
    if (step === "company") {
      onBack();
    } else if (step === "representative") {
      setStep("company");
    } else if (step === "documents") {
      setStep("representative");
    } 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={<UserRound className="size-5" />}
            active={step === "representative"}
            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 === "representative" && `Step 2 of ${totalSteps} — Representative Details`}
          {step === "documents" && `Step 3 of ${totalSteps} — Upload Documents (Optional)`}
          {step === "confirm" && `Step 4 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="Djibouti Logistics SARL"
                  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="info@djib-logistics.dj"
                    aria-invalid={Boolean(errors.companyEmail)}
                    {...register("companyEmail")}
                  />
                  <FieldError errors={[errors.companyEmail]} />
                </Field>

                <PhoneInput
                  countryCode={{ ...register("companyPhoneCountryCode") }}
                  phone={{
                    ...register("companyPhone"),
                    placeholder: "12345678",
                  }}
                  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 / Country</FieldLabel>
                  <Input
                    placeholder="Djibouti City, Djibouti"
                    aria-invalid={Boolean(errors.companyLocation)}
                    {...register("companyLocation")}
                  />
                  <FieldError errors={[errors.companyLocation]} />
                </Field>

                <Field data-invalid={Boolean(errors.companyAddress)}>
                  <FieldLabel>Address</FieldLabel>
                  <Input
                    placeholder="Boulevard de la République"
                    aria-invalid={Boolean(errors.companyAddress)}
                    {...register("companyAddress")}
                  />
                  <FieldError errors={[errors.companyAddress]} />
                </Field>
              </div>
            </>
          )}

          {step === "representative" && (
            <>
              <p className="text-sm text-muted-foreground">
                Provide the company representative details for this account.
              </p>

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

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

                <PhoneInput
                  countryCode={{ ...register("repPhoneCountryCode") }}
                  phone={{
                    ...register("repPhone"),
                    placeholder: "12345678",
                  }}
                  countryCodeError={errors.repPhoneCountryCode}
                  phoneError={errors.repPhone}
                  label="Representative Phone"
                />
              </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="Rep. name" value={formValues.repName} />
                <ReviewRow label="Rep. email" value={formValues.repEmail} />
                <ReviewRow
                  label="Rep. phone"
                  value={`${formValues.repPhoneCountryCode}${formValues.repPhone}`}
                />
              </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">
            {step === "documents" && (
              <Button
                type="button"
                variant="outline"
                onClick={skipDocuments}
                disabled={isPending}
              >
                Skip for now
              </Button>
            )}

            <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>
  );
}
