"use client";

import * as React from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useRouter } from "next/navigation";
import {
  Building2,
  CheckCircle2,
  FileCheck2,
  MapPin,
  UserRound,
} from "lucide-react";
import { toast } from "sonner";

import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Typography } from "@/components/ui/typography";
import { LegalConsent } from "@/components/legal/LegalConsent";
import { useTranslation } from "@/hooks/useTranslation";
import { useRegisterProvider } from "@/hooks/auth/useRegisterProvider";
import { getApiErrorMessage } from "@/lib/api/error";
import { ROUTES } from "@/lib/constants/routes";
import {
  registrationSchema,
  type RegistrationFormValues,
} from "@/lib/validations/provider-registration.schema";
import type { DocumentType } from "@/types/provider";
import type {
  RegisterProviderRequest,
  RegisterDocumentPayload,
} from "@/types/auth";
import type { UploadedFileRef } from "@/types/upload";

import { FormSection } from "./FormSection";
import { RegisterMarketingPanel } from "./RegisterMarketingPanel";
import { AccountSection } from "./AccountSection";
import { BusinessSection } from "./BusinessSection";
import { StationSection } from "./StationSection";
import { DocumentsSection } from "./DocumentsSection";
import type { DocumentUploads } from "./types";

/**
 * Provider self-registration — a single-page form (no stepper). All sections
 * (owner account with mobile OTP, business, service station + map, KYC
 * documents) live in one scrolling form beside a marketing panel. The flat
 * `registrationSchema` validates the whole form on submit; three pieces live
 * outside react-hook-form and are merged into the payload here: the OTP
 * `phoneVerified` gate, the `logo`, and the `documents`.
 */
export function RegisterProviderForm() {
  const { t } = useTranslation();
  const router = useRouter();

  const [phoneVerified, setPhoneVerified] = React.useState(false);
  const [logo, setLogo] = React.useState<UploadedFileRef | null>(null);
  const [documents, setDocuments] = React.useState<DocumentUploads>({});
  const [succeeded, setSucceeded] = React.useState(false);

  const form = useForm<RegistrationFormValues>({
    resolver: zodResolver(registrationSchema),
    // Validate on change and on blur so errors surface as the user edits.
    mode: "all",
    defaultValues: {
      firstName: "",
      lastName: "",
      email: "",
      phoneNumber: "",
      password: "",
      confirmPassword: "",
      businessName: "",
      stationAddress: "",
      stationCity: "",
      stationState: "",
      stationZipCode: "",
      stationLatitude: undefined,
      stationLongitude: undefined,
      serviceRadiusKm: 10,
    },
  });

  const registerMutation = useRegisterProvider({
    onSuccess: () => setSucceeded(true),
    onError: (error) => {
      const status = (error as { response?: { status?: number } })?.response
        ?.status;
      // 409 = business name conflict; 400 = account-level (email/phone) issues.
      if (status === 409) {
        form.setError("businessName", {
          message: "auth.registerProvider.errors.businessNameTaken",
        });
        form.setFocus("businessName");
      } else if (status === 400) {
        form.setFocus("email");
      }
      toast.error(
        getApiErrorMessage(error, t("auth.registerProvider.errors.generic")),
      );
    },
  });

  function setDocument(type: DocumentType, file: UploadedFileRef | null) {
    setDocuments((prev) => {
      const next = { ...prev };
      if (file) next[type] = file;
      else delete next[type];
      return next;
    });
  }

  function buildPayload(v: RegistrationFormValues): RegisterProviderRequest {
    const docs: RegisterDocumentPayload[] = (
      Object.keys(documents) as DocumentType[]
    )
      .filter((type) => documents[type])
      .map((type) => ({ documentType: type, s3Key: documents[type]!.s3Key }));

    return {
      businessName: v.businessName.trim(),
      phoneNumber: v.phoneNumber,
      email: v.email.trim(),
      password: v.password,
      firstName: v.firstName.trim(),
      lastName: v.lastName.trim(),
      stationAddress: v.stationAddress.trim(),
      stationCity: v.stationCity.trim(),
      stationState: v.stationState?.trim() || undefined,
      stationZipCode: v.stationZipCode?.trim() || undefined,
      stationLatitude: v.stationLatitude as number,
      stationLongitude: v.stationLongitude as number,
      serviceRadiusKm: v.serviceRadiusKm,
      logoS3Key: logo?.s3Key,
      documents: docs.length ? docs : undefined,
    };
  }

  function onValid(values: RegistrationFormValues) {
    // The backend rejects registration unless the mobile number is OTP-verified.
    if (!phoneVerified) {
      toast.error(t("auth.registerProvider.account.verifyRequired"));
      form.setFocus("phoneNumber");
      return;
    }
    registerMutation.mutate(buildPayload(values));
  }

  function onInvalid() {
    toast.error(t("auth.registerProvider.errors.fixHighlighted"));
  }

  // ── Success ────────────────────────────────────────────────────────────────
  if (succeeded) {
    return (
      <Card className="w-full max-w-md">
        <CardHeader className="flex flex-col items-center gap-3 text-center">
          <div className="flex size-16 items-center justify-center rounded-full bg-success-light">
            <CheckCircle2 className="size-8 text-success" />
          </div>
          <CardTitle>{t("auth.registerProvider.success.title")}</CardTitle>
          <CardDescription>
            {t("auth.registerProvider.success.body")}
          </CardDescription>
        </CardHeader>
        <CardContent className="flex flex-col gap-3">
          <Button
            type="button"
            className="w-full"
            onClick={() => router.push(ROUTES.SUPPLIER.DASHBOARD)}
          >
            {t("auth.registerProvider.success.goToDashboard")}
          </Button>
          <Button
            type="button"
            variant="ghost"
            className="w-full"
            onClick={() => router.push(ROUTES.AUTH.LOGIN)}
          >
            {t("auth.registerProvider.success.backToLogin")}
          </Button>
        </CardContent>
      </Card>
    );
  }

  // ── Single-page form ─────────────────────────────────────────────────────
  // Desktop: the card is a fixed viewport-height panel — the marketing column
  // and the form's header/footer stay put while ONLY the middle sections scroll
  // (`lg:` classes). Mobile: everything reverts to natural page flow.
  return (
    <div className="w-full max-w-6xl lg:h-[calc(100svh-7rem)]">
      <div className="flex flex-col overflow-hidden rounded-[20px] border border-border bg-card shadow-sm lg:h-full lg:flex-row">
        {/* Marketing panel — compact band on mobile, fixed right column on desktop */}
        <RegisterMarketingPanel className="order-1 lg:order-2 lg:w-[42%] lg:shrink-0" />

        {/* Form — header + footer fixed, middle scrolls (desktop) */}
        <form
          noValidate
          onSubmit={form.handleSubmit(onValid, onInvalid)}
          className="order-2 flex min-h-0 flex-1 flex-col lg:order-1"
        >
          <div className="flex shrink-0 flex-col gap-1 border-b border-border px-5 pt-5 pb-4 sm:px-8 sm:pt-7">
            <Typography as="h1" variant="h1">
              {t("auth.registerProvider.title")}
            </Typography>
            <Typography variant="body" color="secondary">
              {t("auth.registerProvider.subtitle")}
            </Typography>
          </div>

          {/* `relative` makes this scroll region a positioning context so any
              absolutely-positioned descendant (e.g. Leaflet's map panes, whose
              containing block would otherwise be <body>) is contained and
              clipped here — without it those escape and inflate page scroll
              height inside the fixed-height desktop card. */}
          <div className="relative flex flex-col gap-8 px-5 py-6 sm:px-8 lg:min-h-0 lg:flex-1 lg:overflow-y-auto">
            <FormSection
              icon={UserRound}
              title={t("auth.registerProvider.account.title")}
              subtitle={t("auth.registerProvider.account.subtitle")}
            >
              <AccountSection
                form={form}
                phoneVerified={phoneVerified}
                setPhoneVerified={setPhoneVerified}
              />
            </FormSection>

            <FormSection
              icon={Building2}
              title={t("auth.registerProvider.business.title")}
              subtitle={t("auth.registerProvider.business.subtitle")}
            >
              <BusinessSection form={form} logo={logo} setLogo={setLogo} />
            </FormSection>

            <FormSection
              icon={MapPin}
              title={t("auth.registerProvider.location.title")}
              subtitle={t("auth.registerProvider.location.subtitle")}
            >
              <StationSection form={form} />
            </FormSection>

            <FormSection
              icon={FileCheck2}
              title={t("auth.registerProvider.documents.title")}
              subtitle={t("auth.registerProvider.documents.subtitle")}
            >
              <DocumentsSection
                documents={documents}
                setDocument={setDocument}
              />
            </FormSection>
          </div>

          <div className="flex shrink-0 flex-col gap-3 border-t border-border px-5 py-4 sm:px-8">
            <Button
              type="submit"
              className="w-full"
              loading={registerMutation.isPending}
              // Disabled until the mobile number is OTP-verified AND the whole
              // form passes validation (react-hook-form `mode: "all"` keeps
              // `isValid` live). Inline field errors still guide the user.
              disabled={
                registerMutation.isPending ||
                !phoneVerified ||
                !form.formState.isValid
              }
            >
              {t("auth.registerProvider.nav.submit")}
            </Button>
            <LegalConsent messageKey="legal.signupConsent" />
          </div>
        </form>
      </div>
    </div>
  );
}
