"use client";
import { useMemo, useState, type ReactNode } from "react";
import { useForm, type Path } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useLocale, useTranslations } from "next-intl";
import { AlertCircle, Loader2, Lock, Mail, Phone, UserRound } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  createInviteSchema,
  type InviteFormData,
  type InviteFormInput,
} from "@/lib/schemas/invite";
import { acceptInvitation } from "@/services/invitationService";
import { isInviteExpired, type InvitePayload } from "@/lib/invite";

interface RegisterStepProps {
  invite: InvitePayload;
  onExpired: () => void;
  onBack: () => void;
  onSuccess: (data: InviteFormData) => void;
}

const FIELDS = ["name", "email", "phone", "password"] as const;
const INVITE_FIELDS = [
  "company_id",
  "company_name",
  "work_place_id",
  "employee_type",
];

function Field({
  id,
  label,
  icon,
  error,
  children,
}: {
  id: string;
  label: string;
  icon: ReactNode;
  error?: string;
  children: ReactNode;
}) {
  return (
    <div className="flex flex-col gap-2">
      <label
        htmlFor={id}
        className="flex items-center gap-2 text-[14px] sm:text-[16px] font-bold"
      >
        <span className="text-secondary-main">{icon}</span>
        {label}
        <span className="text-error-lighter">*</span>
      </label>
      {children}
      {error && (
        <p className="flex items-center gap-1.5 text-[13px] text-error-lighter">
          <AlertCircle className="size-3.5 shrink-0" />
          {error}
        </p>
      )}
    </div>
  );
}

export default function RegisterStep({
  invite,
  onExpired,
  onBack,
  onSuccess,
}: RegisterStepProps) {
  const t = useTranslations("InvitePage");
  const locale = useLocale();
  const [serverError, setServerError] = useState<string | null>(null);
  const schema = useMemo(() => createInviteSchema(t), [t]);

  const {
    register,
    handleSubmit,
    setError,
    formState: { errors, isSubmitting },
  } = useForm<InviteFormInput, unknown, InviteFormData>({
    resolver: zodResolver(schema),
    defaultValues: { name: "", email: "", phone: "", password: "" },
  });

  const onSubmit = async (data: InviteFormData) => {
    setServerError(null);
    if (isInviteExpired(invite.x)) {
      onExpired();
      return;
    }
    const result = await acceptInvitation(data, invite, locale);

    if (result.ok) {
      onSuccess(data);
      return;
    }

    let hasFieldError = false;
    let hasInviteError = false;
    let otherError: string | undefined;
    Object.entries(result.fieldErrors ?? {}).forEach(([field, messages]) => {
      if (!messages?.[0]) return;
      if ((FIELDS as readonly string[]).includes(field)) {
        setError(field as Path<InviteFormInput>, {
          type: "server",
          message: messages[0],
        });
        hasFieldError = true;
      } else if (INVITE_FIELDS.includes(field)) {
        // Company / work place in the link no longer exists
        hasInviteError = true;
      } else {
        otherError ??= messages[0];
      }
    });

    if (hasInviteError) {
      setServerError(t("inviteNoLongerValid"));
    } else if (!hasFieldError) {
      // Package limits, expired subscriptions, etc. arrive as a plain message;
      // validation responses only carry a generic "failed"
      setServerError(
        otherError ||
          (result.fieldErrors ? undefined : result.message) ||
          t("genericError"),
      );
    }
  };

  return (
    <form
      onSubmit={handleSubmit(onSubmit)}
      noValidate
      className="flex flex-col gap-6 sm:gap-8"
    >
      <div className="flex flex-col gap-2">
        <h1 className="text-[22px] sm:text-[28px] font-bold">
          {t("completeTitle")}
        </h1>
        <p className="text-[14px] sm:text-[16px] text-white/70">
          {t("completeDescription", { company: invite.cn })}
        </p>
      </div>

      {serverError && (
        <div
          role="alert"
          className="flex items-start gap-3 rounded-[16px] border border-error-lighter/40 bg-error-lighter/10 p-4 text-[14px]"
        >
          <AlertCircle className="size-5 shrink-0 text-error-lighter" />
          <span>{serverError}</span>
        </div>
      )}

      <div className="flex flex-col gap-5">
        <Field
          id="invite-name"
          label={t("fullName")}
          icon={<UserRound className="size-4" />}
          error={errors.name?.message}
        >
          <Input
            id="invite-name"
            autoComplete="name"
            placeholder={t("fullNamePlaceholder")}
            aria-invalid={Boolean(errors.name)}
            {...register("name")}
          />
        </Field>

        <Field
          id="invite-email"
          label={t("email")}
          icon={<Mail className="size-4" />}
          error={errors.email?.message}
        >
          <Input
            id="invite-email"
            type="email"
            dir="ltr"
            autoComplete="email"
            placeholder="name@company.com"
            aria-invalid={Boolean(errors.email)}
            className="text-left"
            {...register("email")}
          />
        </Field>

        <Field
          id="invite-phone"
          label={t("phone")}
          icon={<Phone className="size-4" />}
          error={errors.phone?.message}
        >
          <Input
            id="invite-phone"
            type="tel"
            inputMode="numeric"
            autoComplete="tel"
            placeholder="05XXXXXXXX"
            aria-invalid={Boolean(errors.phone)}
            {...register("phone")}
          />
        </Field>

        <Field
          id="invite-password"
          label={t("password")}
          icon={<Lock className="size-4" />}
          error={errors.password?.message}
        >
          <Input
            id="invite-password"
            type="password"
            autoComplete="new-password"
            placeholder={t("passwordPlaceholder")}
            aria-invalid={Boolean(errors.password)}
            {...register("password")}
          />
        </Field>
      </div>

      <div className="flex flex-col-reverse sm:flex-row gap-3">
        <Button
          type="button"
          variant="outline"
          onClick={onBack}
          disabled={isSubmitting}
          className="border-white/40 text-white hover:bg-white/10 hover:text-white sm:w-auto"
        >
          {t("back")}
        </Button>
        <Button type="submit" disabled={isSubmitting} className="flex-1 font-bold">
          {isSubmitting && <Loader2 className="size-5 animate-spin" />}
          {isSubmitting ? t("creatingAccount") : t("createAccount")}
        </Button>
      </div>
    </form>
  );
}
