import { Box, Button, Group, Loader, SimpleGrid, Stack, Text, TextInput, ThemeIcon } from "@mantine/core";
import { zodResolver } from "@hookform/resolvers/zod";
import { useQuery } from "@tanstack/react-query";
import {
  ArrowLeft,
  ArrowRight,
  Building2,
  CheckCircle2,
  ChevronLeft,
  UploadCloud,
  UserRound,
} from "lucide-react";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";

import type { AuthUser } from "@/types/auth";
import type { CreateCompanyPayload } from "@/services/companies.service";
import { ControlledPhoneField, isValidPhone } from "@/components/PhoneField";
import { 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")
    .refine(isValidPhone, "Enter a valid phone number"),
  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")
    .refine(isValidPhone, "Enter a valid phone number"),
});

type FormData = z.infer<typeof djiboutiSchema>;

const stepFields: Record<DjiboutiStep, (keyof FormData)[]> = {
  company: ["companyName", "companyEmail", "companyPhone", "companyLocation", "companyAddress"],
  representative: ["repName", "repEmail", "repPhone"],
  documents: [],
  confirm: [],
};

function buildPayload(data: FormData, _user: AuthUser): CreateCompanyPayload {
  return {
    companyName: data.companyName,
    companyEmail: data.companyEmail,
    companyPhone: data.companyPhone,
    companyLocation: data.companyLocation,
    companyAddress: data.companyAddress,
    tin: "",
    vatNumber: "",
    fanNumber: "",
    attributes: {
      repName: data.repName,
      repEmail: data.repEmail,
      repPhone: 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, control, handleSubmit, trigger, watch, formState: { errors } } = useForm<FormData>({
    resolver: zodResolver(djiboutiSchema),
    defaultValues: {
      companyName: "", companyEmail: "", companyPhone: "",
      companyLocation: "", companyAddress: "", repName: "", repEmail: "", repPhone: "",
    },
  });

  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 isValid = await trigger(stepFields[step]);
    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");
  };

  const STEPS: { key: DjiboutiStep; icon: React.ReactNode }[] = [
    { key: "company", icon: <Building2 size={18} /> },
    { key: "representative", icon: <UserRound size={18} /> },
    { key: "documents", icon: <UploadCloud size={18} /> },
    { key: "confirm", icon: <CheckCircle2 size={18} /> },
  ];

  const STEP_LABELS: Record<DjiboutiStep, string> = {
    company: `Step 1 of ${totalSteps} — Company Information`,
    representative: `Step 2 of ${totalSteps} — Representative Details`,
    documents: `Step 3 of ${totalSteps} — Upload Documents (Optional)`,
    confirm: `Step 4 of ${totalSteps} — Review & Confirm`,
  };

  const stepOrder: DjiboutiStep[] = ["company", "representative", "documents", "confirm"];
  const currentIdx = stepOrder.indexOf(step);

  return (
    <>
      <Box mb="xl">
        <Button
          variant="subtle"
          c="edr-muted"
          size="sm"
          mb="sm"
          leftSection={<ChevronLeft size={16} />}
          onClick={prevStep}
        >
          Change account type
        </Button>

        <Group justify="space-between" align="center" className="relative max-w-lg mx-auto px-2">
          <Box className="absolute top-1/2 left-2 right-2 h-0.5 bg-edr-border -translate-y-1/2 z-0" />
          {STEPS.map(({ key, icon }, i) => {
            const done = i < currentIdx;
            const active = i === currentIdx;
            return done || active ? (
              <ThemeIcon key={key} size={40} radius="xl" variant="filled" color="edr-green" className="relative z-10">
                {done ? <CheckCircle2 size={18} /> : icon}
              </ThemeIcon>
            ) : (
              <Box
                key={key}
                w={40}
                h={40}
                c="edr-slate"
                className="relative z-10 flex items-center justify-center rounded-full border-2 border-edr-border bg-edr-card"
              >
                {icon}
              </Box>
            );
          })}
        </Group>

        <Text size="sm" c="edr-muted" ta="center" mt="sm">
          {STEP_LABELS[step]}
        </Text>
      </Box>

      <form onSubmit={(e) => e.preventDefault()}>
        <Stack gap="md">
          {step === "company" && (
            <>
              <TextInput
                label="Company Name"
                placeholder="Djibouti Logistics SARL"
                error={errors.companyName?.message}
                {...register("companyName")}
              />
              <SimpleGrid cols={2} spacing="md">
                <TextInput
                  label="Company Email"
                  type="email"
                  placeholder="info@djib-logistics.dj"
                  error={errors.companyEmail?.message}
                  {...register("companyEmail")}
                />
                <ControlledPhoneField
                  control={control}
                  name="companyPhone"
                  label="Company Phone"
                  required
                />
              </SimpleGrid>
              <SimpleGrid cols={2} spacing="md">
                <TextInput
                  label="Location / Country"
                  placeholder="Djibouti City, Djibouti"
                  error={errors.companyLocation?.message}
                  {...register("companyLocation")}
                />
                <TextInput
                  label="Address"
                  placeholder="Boulevard de la République"
                  error={errors.companyAddress?.message}
                  {...register("companyAddress")}
                />
              </SimpleGrid>
            </>
          )}

          {step === "representative" && (
            <>
              <Text size="sm" c="edr-muted">
                Provide the company representative details for this account.
              </Text>
              <TextInput
                label="Representative Name"
                placeholder="Ahmed Hassan"
                error={errors.repName?.message}
                {...register("repName")}
              />
              <SimpleGrid cols={2} spacing="md">
                <TextInput
                  label="Representative Email"
                  type="email"
                  placeholder="ahmed@company.dj"
                  error={errors.repEmail?.message}
                  {...register("repEmail")}
                />
                <ControlledPhoneField
                  control={control}
                  name="repPhone"
                  label="Representative Phone"
                  required
                />
              </SimpleGrid>
            </>
          )}

          {step === "documents" && (
            <>
              {loadingDocuments ? (
                <Group justify="center" py="xl">
                  <Loader size="sm" color="edr-green" />
                </Group>
              ) : !uploadSetting ? (
                <Text size="sm" c="edr-muted" ta="center" py="md">
                  No document requirements found for your account type.
                </Text>
              ) : (
                <SmartFileInput file={uploadSetting} value={documentFiles} onChange={setDocumentFiles} />
              )}
            </>
          )}

          {step === "confirm" && (
            <Box p={16} className="rounded-2xl border border-edr-border bg-edr-card">
              <Text fw={600} c="edr-text">Review your registration</Text>
              <Text size="sm" c="edr-muted" mt={4} mb="md">
                Confirm the company details below before saving.
              </Text>
              <SimpleGrid cols={2} spacing="sm">
                <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.repPhone} />
              </SimpleGrid>
            </Box>
          )}

          <Group justify="space-between" pt="xs">
            <Button variant="default" onClick={prevStep} leftSection={<ArrowLeft size={16} />}>
              {step === "company" ? "Change Type" : step === "confirm" ? "Back to Documents" : "Back"}
            </Button>
            <Group gap="sm">
              {step === "documents" && (
                <Button variant="default" onClick={skipDocuments} disabled={isPending}>
                  Skip for now
                </Button>
              )}
              <Button
                color="edr-green"
                onClick={step === "confirm" ? handleSubmit((data) => onSubmit(buildPayload(data, user))) : nextStep}
                disabled={isPending || (step === "documents" && !hasDocuments && loadingDocuments)}
                loading={isPending}
                rightSection={!isPending && step !== "confirm" && step !== "documents" ? <ArrowRight size={16} /> : undefined}
              >
                {step === "documents" ? "Continue" : step === "confirm" ? "Submit Registration" : "Next Step"}
              </Button>
            </Group>
          </Group>
        </Stack>
      </form>
    </>
  );
}

function ReviewRow({ label, value }: { label: string; value?: string | null }) {
  return (
    <Box p={12} className="rounded-xl bg-edr-bg">
      <Text size="xs" fw={600} c="edr-muted" className="uppercase tracking-wide">
        {label}
      </Text>
      <Text size="sm" fw={500} c={value?.trim() ? "edr-text" : "edr-muted"} mt={4}>
        {value?.trim() ? value : "Not provided"}
      </Text>
    </Box>
  );
}
