import { useState } from "react";
import { useForm } from "react-hook-form";
import { useNavigate, Link } from "react-router-dom";
import { useTranslation } from "react-i18next";
import {
  FiMail,
  FiLock,
  FiCheckCircle,
  FiUser,
  FiPhone,
  FiMapPin,
} from "react-icons/fi";
import { apiAccountRegisterCreate } from "@/api/generated/public/account";
import Card from "@/components/ui/Card";
import Input from "@/components/ui/Input";
import Button from "@/components/ui/Button";
import Checkbox from "@/components/ui/Checkbox";
import Spinner from "@/components/ui/Spinner";
import FormErrorBanner from "@/components/ui/FormErrorBanner";
import { applyServerErrors } from "@/utils/formErrors";
import { useTurnstile } from "@/hooks/useTurnstile";

interface RegisterForm {
  username: string;
  email: string;
  password: string;
  password2: string;
  gdpr: boolean;
  first_name: string;
  last_name: string;
  phone_number: string;
  city: string;
  street: string;
  postal_code: string;
}

export default function RegisterPage() {
  const { t } = useTranslation("auth");
  const navigate = useNavigate();
  const [rootError, setRootError] = useState<string | undefined>();
  const [success, setSuccess] = useState(false);
  const { containerRef, token: turnstileToken, enabled: turnstileEnabled, reset: resetTurnstile } = useTurnstile();

  const form = useForm<RegisterForm>({
    defaultValues: {
      username: "",
      email: "",
      password: "",
      password2: "",
      gdpr: false,
      first_name: "",
      last_name: "",
      phone_number: "",
      city: "",
      street: "",
      postal_code: "",
    },
  });
  const { register, handleSubmit, formState, getValues, clearErrors } = form;
  const { errors, isSubmitting } = formState;

  async function onSubmit(values: RegisterForm) {
    if (!turnstileToken) return;
    setRootError(undefined);
    // Wipe any stale server errors before the new request — RHF only
    // re-validates fields that have rules, so server errors on optional
    // fields (first_name, address, etc.) would otherwise stick forever.
    clearErrors();
    const { password2: _ignore, ...payload } = values;
    void _ignore;
    try {
      // BE serializer doesn't know about password2; strip before sending.
      // Cast to the orval-generated type — fields may be re-typed as optional
      // once the schema is regenerated via `npm run api:gen`.
      await apiAccountRegisterCreate(
        { ...payload, turnstile_token: turnstileToken ?? "" } as Parameters<typeof apiAccountRegisterCreate>[0],
      );
      setSuccess(true);
      setTimeout(() => navigate("/social/login"), 1500);
    } catch (err) {
      setRootError(applyServerErrors(form, err) ?? t("register.errors.generic"));
      resetTurnstile();
    }
  }

  function onInvalid() {
    // Client validation blocked submit — clear the stale root banner.
    setRootError(undefined);
  }

  if (success) {
    return (
      <div className="min-h-screen flex items-center justify-center p-4">
        <Card className="w-full max-w-md text-center" padded>
          <FiCheckCircle className="mx-auto text-brand-accent" size={56} />
          <h1 className="mt-3 text-2xl font-bold text-brand-text">
            {t("register.successTitle")}
          </h1>
          <p className="mt-2 text-brand-text/70">{t("register.successBody")}</p>
        </Card>
      </div>
    );
  }

  return (
    <div className="min-h-screen flex items-center justify-center p-4">
      <Card className="w-full max-w-md" padded={false}>
        <div className="px-8 pt-8 pb-2">
          <h1 className="text-3xl font-bold text-rainbow">
            {t("register.title")}
          </h1>
          <p className="mt-1 text-sm text-brand-text/70">
            {t("register.subtitle")}
          </p>
        </div>

        <form
          onSubmit={handleSubmit(onSubmit, onInvalid)}
          className="space-y-4 p-8"
          noValidate
        >
          <FormErrorBanner message={rootError} />

          <Input
            type="email"
            label={t("register.usernameLabel")}
            icon={<FiUser />}
            autoComplete="username"
            disabled={isSubmitting}
            error={errors.username?.message}
            {...register("username", { required: t("register.errors.usernameRequired") })}
          />

          <Input
            type="email"
            label={t("register.emailLabel")}
            icon={<FiMail />}
            autoComplete="email"
            disabled={isSubmitting}
            error={errors.email?.message}
            {...register("email", { required: t("register.errors.emailRequired") })}
          />

          <Input
            type="password"
            label={t("register.passwordLabel")}
            icon={<FiLock />}
            autoComplete="new-password"
            disabled={isSubmitting}
            error={errors.password?.message}
            {...register("password", {
              required: t("register.errors.passwordRequired"),
              minLength: { value: 8, message: t("register.errors.tooShort") },
            })}
          />
          <p className="-mt-3 text-xs text-brand-text/60">
            {t("register.passwordHint")}
          </p>

          <Input
            type="password"
            label={t("register.password2Label")}
            icon={<FiLock />}
            autoComplete="new-password"
            disabled={isSubmitting}
            error={errors.password2?.message}
            {...register("password2", {
              required: t("register.errors.password2Required"),
              validate: (v) =>
                v === getValues("password") || t("register.errors.mismatch"),
            })}
          />

          <Checkbox
            label={t("register.gdprLabel")}
            disabled={isSubmitting}
            error={errors.gdpr?.message}
            {...register("gdpr", {
              validate: (value) => value || t("register.errors.gdprRequired"),
            })}
          />

          <details className="rounded-xl px-3 py-2">
            <summary className="cursor-pointer text-sm text-brand-text/80 select-none">
              {t("register.optionalToggle")}
            </summary>
            <div className="mt-3 space-y-3">
              <div className="grid grid-cols-2 gap-3">
                <Input
                  label={t("register.fields.firstName")}
                  icon={<FiUser />}
                  autoComplete="given-name"
                  disabled={isSubmitting}
                  error={errors.first_name?.message}
                  {...register("first_name")}
                />
                <Input
                  label={t("register.fields.lastName")}
                  icon={<FiUser />}
                  autoComplete="family-name"
                  disabled={isSubmitting}
                  error={errors.last_name?.message}
                  {...register("last_name")}
                />
              </div>

              <Input
                label={t("register.fields.phone")}
                icon={<FiPhone />}
                placeholder="+420..."
                autoComplete="tel"
                disabled={isSubmitting}
                error={errors.phone_number?.message}
                {...register("phone_number")}
              />

              <Input
                label={t("register.fields.street")}
                icon={<FiMapPin />}
                autoComplete="street-address"
                disabled={isSubmitting}
                error={errors.street?.message}
                {...register("street")}
              />

              <div className="grid grid-cols-2 gap-3">
                <Input
                  label={t("register.fields.city")}
                  icon={<FiMapPin />}
                  autoComplete="address-level2"
                  disabled={isSubmitting}
                  error={errors.city?.message}
                  {...register("city")}
                />
                <Input
                  label={t("register.fields.postalCode")}
                  autoComplete="postal-code"
                  disabled={isSubmitting}
                  error={errors.postal_code?.message}
                  {...register("postal_code")}
                />
              </div>
            </div>
          </details>

          {turnstileEnabled && <div ref={containerRef} className="flex justify-center" />}

          <Button type="submit" fullWidth loading={isSubmitting} disabled={isSubmitting || !turnstileToken}>
            {isSubmitting ? (
              <>
                <Spinner size={16} /> {t("register.submitting")}
              </>
            ) : (
              t("register.submit")
            )}
          </Button>

          <p className="text-center text-sm text-brand-text/70">
            {t("register.haveAccount")}{" "}
            <Link
              to="/social/login"
              className="font-semibold text-brand-accent hover:underline"
            >
              {t("register.loginCta")}
            </Link>
          </p>
        </form>
      </Card>
    </div>
  );
}
