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

import type { AuthUser } from "@/types/auth";
import type { CreateCompanyPayload } from "@/services/companies.service";
import { SmartFileInput } from "@edr/ui-common";
import { api } from "@/services/api";

const TRUCK_TYPES = ["Casoni", "Truck Trailer", "High Bed", "Low Bed", "Others"] as const;

type TransporterStep = "vehicle" | "documents" | "confirm";

const transporterSchema = z
  .object({
    tinNumber: z.string().length(10, "TIN must be exactly 10 digits"),
    fanNumber: z.string().length(16, "FAN must be exactly 16 digits"),
    truckType: z.string().min(1, "Truck type is required"),
    plateNumber: z.string().min(1, "Plate number is required"),
    plateNumber2: z.string().optional(),
    vehicleModel: z.string().min(1, "Vehicle model is required"),
    yearOfManufacturing: z
      .string()
      .min(1, "Year of manufacturing is required")
      .regex(/^\d{4}$/, "Enter a valid year (e.g. 2023)"),
  })
  .superRefine((data, ctx) => {
    if (data.truckType === "Casoni" && (!data.plateNumber2 || data.plateNumber2.trim().length === 0)) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["plateNumber2"],
        message: "Second plate number is required for Casoni",
      });
    }
  });

type FormData = z.infer<typeof transporterSchema>;

function buildPayload(data: FormData, user: AuthUser): CreateCompanyPayload {
  return {
    companyName: user.name?.en ?? "",
    companyEmail: user.email,
    companyPhone: user.phoneNumber,
    companyLocation: "",
    companyAddress: "",
    tin: data.tinNumber,
    vatNumber: "",
    fanNumber: data.fanNumber,
    attributes: {
      truckType: data.truckType,
      plateNumber: data.plateNumber,
      plateNumber2: data.plateNumber2 || null,
      vehicleModel: data.vehicleModel,
      yearOfManufacturing: data.yearOfManufacturing,
    },
  };
}

export default function TransporterForm({
  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<TransporterStep>("vehicle");
  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, control, formState: { errors } } = useForm<FormData>({
    resolver: zodResolver(transporterSchema),
    defaultValues: {
      tinNumber: "", fanNumber: "", truckType: "", plateNumber: "", plateNumber2: "", vehicleModel: "", yearOfManufacturing: "",
    },
  });

  const truckType = watch("truckType");
  const isCasoni = truckType === "Casoni";
  const formValues = watch();
  const hasDocuments = Boolean(uploadSetting?.fields?.length);
  const totalSteps = 3;

  const nextStep = async () => {
    if (step === "documents") { setStep("confirm"); return; }
    if (step === "confirm") { handleSubmit((data) => onSubmit(buildPayload(data, user)))(); return; }
    const fields: (keyof FormData)[] = ["tinNumber", "fanNumber", "truckType", "plateNumber", "vehicleModel", "yearOfManufacturing"];
    const isValid = await trigger(fields);
    if (!isValid) return;
    setStep("documents");
  };

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

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

  const STEPS: { key: TransporterStep; icon: React.ReactNode }[] = [
    { key: "vehicle", icon: <Truck size={18} /> },
    { key: "documents", icon: <UploadCloud size={18} /> },
    { key: "confirm", icon: <CheckCircle2 size={18} /> },
  ];

  const STEP_LABELS: Record<TransporterStep, string> = {
    vehicle: `Step 1 of ${totalSteps} — Vehicle Information`,
    documents: `Step 2 of ${totalSteps} — Upload Documents (Optional)`,
    confirm: `Step 3 of ${totalSteps} — Review & Confirm`,
  };

  const stepOrder: TransporterStep[] = ["vehicle", "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 === "vehicle" && (
            <>
              <SimpleGrid cols={2} spacing="md">
                <TextInput
                  label="TIN Number (10 digits)"
                  placeholder="1234567890"
                  maxLength={10}
                  error={errors.tinNumber?.message}
                  {...register("tinNumber")}
                />
                <TextInput
                  label="FAN Number (16 digits)"
                  placeholder="1234567890123456"
                  maxLength={16}
                  error={errors.fanNumber?.message}
                  {...register("fanNumber")}
                />
              </SimpleGrid>

              <Divider color="edr-border" />

              <Text fw={600} size="sm" c="edr-text">Vehicle / Truck Information</Text>

              <Controller
                name="truckType"
                control={control}
                render={({ field, fieldState }) => (
                  <Select
                    label="Truck Type"
                    placeholder="Select truck type..."
                    data={TRUCK_TYPES as unknown as string[]}
                    value={field.value || null}
                    onChange={(v) => field.onChange(v ?? "")}
                    error={fieldState.error?.message}
                    comboboxProps={{ withinPortal: true }}
                  />
                )}
              />

              <SimpleGrid cols={2} spacing="md">
                <TextInput
                  label={`Plate Number${isCasoni ? " (Front)" : ""}`}
                  placeholder="AA-12345"
                  error={errors.plateNumber?.message}
                  {...register("plateNumber")}
                />
                {isCasoni ? (
                  <TextInput
                    label="Plate Number (Trailer)"
                    placeholder="AA-67890"
                    error={errors.plateNumber2?.message}
                    {...register("plateNumber2")}
                  />
                ) : (
                  <TextInput
                    label="Vehicle Model"
                    placeholder="Isuzu FVR 2024"
                    error={errors.vehicleModel?.message}
                    {...register("vehicleModel")}
                  />
                )}
              </SimpleGrid>

              <SimpleGrid cols={2} spacing="md">
                {isCasoni && (
                  <TextInput
                    label="Vehicle Model"
                    placeholder="Isuzu FVR 2024"
                    error={errors.vehicleModel?.message}
                    {...register("vehicleModel")}
                  />
                )}
                <TextInput
                  label="Year of Manufacturing"
                  placeholder="2023"
                  maxLength={4}
                  error={errors.yearOfManufacturing?.message}
                  {...register("yearOfManufacturing")}
                />
              </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 details below before saving.
              </Text>
              <SimpleGrid cols={2} spacing="sm">
                <ReviewRow label="TIN Number" value={formValues.tinNumber} />
                <ReviewRow label="FAN Number" value={formValues.fanNumber} />
                <ReviewRow label="Truck Type" value={formValues.truckType} />
                <ReviewRow label="Plate Number" value={formValues.plateNumber} />
                {formValues.plateNumber2 && <ReviewRow label="Plate (Trailer)" value={formValues.plateNumber2} />}
                <ReviewRow label="Vehicle Model" value={formValues.vehicleModel} />
                <ReviewRow label="Year" value={formValues.yearOfManufacturing} />
              </SimpleGrid>
            </Box>
          )}

          <Group justify="space-between" pt="xs">
            <Button variant="default" onClick={prevStep} leftSection={<ArrowLeft size={16} />}>
              {step === "vehicle" ? "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 border border-edr-border bg-edr-card">
      <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>
  );
}
