"use client";

import * as React from "react";
import { CheckCircle2, Eye, EyeOff } from "lucide-react";

import { FormField } from "@/components/ui/form-field";
import { Input } from "@/components/ui/input";
import {
  InputGroup,
  InputGroupAddon,
  InputGroupButton,
  InputGroupInput,
} from "@/components/ui/input-group";
import { PhoneInput } from "@/components/ui/phone-input";
import { OtpInput } from "@/components/auth/OtpInput";
import { Button } from "@/components/ui/button";
import { Typography } from "@/components/ui/typography";
import { useSendOtp } from "@/hooks/auth/useSendOtp";
import { useVerifyOtp } from "@/hooks/auth/useVerifyOtp";
import { useTranslation } from "@/hooks/useTranslation";
import { getApiErrorMessage } from "@/lib/api/error";
import type { RegistrationForm } from "./types";

const RESEND_COOLDOWN_SECONDS = 30;
/** Matches the schema: +966 followed by 9 digits. */
const SAUDI_PHONE = /^\+966\d{9}$/;

interface AccountSectionProps {
  form: RegistrationForm;
  phoneVerified: boolean;
  setPhoneVerified: (verified: boolean) => void;
}

/**
 * Owner account details with inline mobile OTP verification. The backend rejects
 * registration unless the phone is OTP-verified, so the form can't be submitted
 * until it is. The OTP entry appears directly below the mobile number. A verify
 * that returns `isRegistered: true` means the number already has an account —
 * surfaced inline as "please sign in instead".
 */
export function AccountSection({
  form,
  phoneVerified,
  setPhoneVerified,
}: AccountSectionProps) {
  const { t } = useTranslation();
  const { control } = form;

  const [showPassword, setShowPassword] = React.useState(false);
  const [showConfirm, setShowConfirm] = React.useState(false);
  const [otpSent, setOtpSent] = React.useState(false);
  const [otpCode, setOtpCode] = React.useState("");
  const [cooldown, setCooldown] = React.useState(0);
  const [inlineError, setInlineError] = React.useState<string | null>(null);

  const phoneValue = form.watch("phoneNumber");
  const phoneIsValid = SAUDI_PHONE.test(phoneValue ?? "");

  React.useEffect(() => {
    if (cooldown <= 0) return;
    const timer = setTimeout(() => setCooldown((c) => c - 1), 1000);
    return () => clearTimeout(timer);
  }, [cooldown]);

  const sendMutation = useSendOtp({
    onSuccess: () => {
      setOtpSent(true);
      setCooldown(RESEND_COOLDOWN_SECONDS);
    },
  });

  const verifyMutation = useVerifyOtp({
    onSuccess: (data) => {
      if (data.isRegistered) {
        setInlineError(t("auth.registerProvider.account.alreadyRegistered"));
        return;
      }
      setPhoneVerified(true);
    },
  });

  async function handleSendOtp() {
    const ok = await form.trigger("phoneNumber");
    if (!ok) return;
    setInlineError(null);
    setOtpCode("");
    sendMutation.mutate({ phoneNumber: form.getValues("phoneNumber") });
  }

  function handleVerify() {
    setInlineError(null);
    verifyMutation.mutate({
      phoneNumber: form.getValues("phoneNumber"),
      code: otpCode,
    });
  }

  /** Editing the number after verifying invalidates the verification. */
  function resetVerification() {
    if (phoneVerified) setPhoneVerified(false);
    setOtpSent(false);
    setOtpCode("");
    setInlineError(null);
  }

  const verifyError =
    inlineError ??
    (verifyMutation.isError
      ? getApiErrorMessage(
          verifyMutation.error,
          t("auth.validation.otpRequired"),
        )
      : null);

  return (
    <div className="flex flex-col gap-5">
      <div className="grid gap-5 sm:grid-cols-2">
        <FormField
          control={control}
          name="firstName"
          label={t("auth.registerProvider.account.firstName")}
          render={({ field, hasError, id }) => (
            <Input
              id={id}
              placeholder={t(
                "auth.registerProvider.account.firstNamePlaceholder",
              )}
              aria-invalid={hasError}
              {...field}
            />
          )}
        />
        <FormField
          control={control}
          name="lastName"
          label={t("auth.registerProvider.account.lastName")}
          render={({ field, hasError, id }) => (
            <Input
              id={id}
              placeholder={t(
                "auth.registerProvider.account.lastNamePlaceholder",
              )}
              aria-invalid={hasError}
              {...field}
            />
          )}
        />
      </div>

      <FormField
        control={control}
        name="email"
        label={t("auth.registerProvider.account.email")}
        render={({ field, hasError, id }) => (
          <Input
            id={id}
            type="email"
            inputMode="email"
            autoComplete="email"
            placeholder={t("auth.registerProvider.account.emailPlaceholder")}
            aria-invalid={hasError}
            {...field}
          />
        )}
      />

      {/* Mobile number + OTP verification (OTP entry sits directly below) */}
      <div className="flex flex-col gap-3">
        <FormField
          control={control}
          name="phoneNumber"
          label={t("auth.registerProvider.account.phone")}
          render={({ field, hasError, id }) => (
            <div className="flex items-start gap-2">
              <PhoneInput
                id={id}
                className="flex-1"
                aria-invalid={hasError}
                value={field.value}
                onChange={(value) => {
                  field.onChange(value);
                  resetVerification();
                }}
                onBlur={field.onBlur}
                disabled={phoneVerified}
              />
              {!phoneVerified && (
                <Button
                  type="button"
                  variant="secondary"
                  onClick={handleSendOtp}
                  loading={sendMutation.isPending}
                  disabled={
                    !phoneIsValid || sendMutation.isPending || cooldown > 0
                  }
                  className="shrink-0"
                >
                  {cooldown > 0
                    ? t("auth.registerProvider.account.resendIn", {
                        seconds: cooldown,
                      })
                    : otpSent
                      ? t("auth.registerProvider.account.resendOtp")
                      : t("auth.registerProvider.account.sendOtp")}
                </Button>
              )}
            </div>
          )}
        />

        {phoneVerified ? (
          <div className="flex items-center gap-2 rounded-[12px] border border-input bg-card p-3">
            <CheckCircle2 className="size-5 shrink-0 text-success" />
            <Typography as="span" variant="body" className="flex-1">
              {t("auth.registerProvider.account.verified")}
            </Typography>
            <Button
              type="button"
              variant="ghost"
              size="sm"
              onClick={resetVerification}
            >
              {t("auth.registerProvider.account.changeNumber")}
            </Button>
          </div>
        ) : otpSent ? (
          <div className="flex flex-col gap-3 rounded-[12px] border border-input bg-card p-4">
            <Typography as="p" variant="caption" color="secondary">
              {t("auth.registerProvider.account.otpSent", {
                phone: phoneValue,
              })}
            </Typography>
            <OtpInput
              value={otpCode}
              onChange={(value) => {
                setOtpCode(value);
                setInlineError(null);
              }}
              hasError={!!verifyError}
            />
            {verifyError && (
              <Typography
                as="p"
                variant="caption"
                className="text-destructive text-center"
              >
                {verifyError}
              </Typography>
            )}
            <Button
              type="button"
              onClick={handleVerify}
              loading={verifyMutation.isPending}
              disabled={otpCode.length !== 6 || verifyMutation.isPending}
            >
              {t("auth.registerProvider.account.verify")}
            </Button>
          </div>
        ) : null}
      </div>

      <FormField
        control={control}
        name="password"
        label={t("auth.registerProvider.account.password")}
        render={({ field, hasError, id }) => (
          <InputGroup>
            <InputGroupInput
              id={id}
              type={showPassword ? "text" : "password"}
              autoComplete="new-password"
              placeholder={t(
                "auth.registerProvider.account.passwordPlaceholder",
              )}
              aria-invalid={hasError}
              {...field}
            />
            <InputGroupAddon align="inline-end">
              <InputGroupButton
                type="button"
                onClick={() => setShowPassword((v) => !v)}
              >
                {showPassword ? (
                  <EyeOff className="size-4 text-muted-foreground" />
                ) : (
                  <Eye className="size-4 text-muted-foreground" />
                )}
              </InputGroupButton>
            </InputGroupAddon>
          </InputGroup>
        )}
      />

      <FormField
        control={control}
        name="confirmPassword"
        label={t("auth.registerProvider.account.confirmPassword")}
        render={({ field, hasError, id }) => (
          <InputGroup>
            <InputGroupInput
              id={id}
              type={showConfirm ? "text" : "password"}
              autoComplete="new-password"
              placeholder={t(
                "auth.registerProvider.account.confirmPasswordPlaceholder",
              )}
              aria-invalid={hasError}
              {...field}
            />
            <InputGroupAddon align="inline-end">
              <InputGroupButton
                type="button"
                onClick={() => setShowConfirm((v) => !v)}
              >
                {showConfirm ? (
                  <EyeOff className="size-4 text-muted-foreground" />
                ) : (
                  <Eye className="size-4 text-muted-foreground" />
                )}
              </InputGroupButton>
            </InputGroupAddon>
          </InputGroup>
        )}
      />
    </div>
  );
}
