"use client";

import { FormEvent, useCallback, useEffect, useState } from "react";
import { Alert } from "../components/Alert";
import { Button } from "../components/Button";
import { Field, Input } from "../components/Field";
import { isValidNationalCode } from "../validation/nationalCode";
import {
  MAX_FOREIGN_IDENTIFIER_LENGTH,
  isCompletePersonIdentifier,
  sanitizePersonIdentifier,
} from "../validation/personIdentifier";
import { validationMessages } from "../validation/messages";

export type ForgotStep = "identity" | "otp" | "password";

export interface ForgotPasswordApi {
  fetchCaptcha: () => Promise<{ key: string; question: string }>;
  forgotPassword: (input: {
    national_code: string;
    captcha_key: string;
    captcha_answer: string;
    is_foreign_national?: boolean;
  }) => Promise<string>;
  verifyForgotOtp: (input: { national_code: string; otp: string }) => Promise<string>;
  resetPassword: (input: {
    national_code: string;
    password: string;
    password_confirmation: string;
  }) => Promise<string>;
}

export interface ForgotPasswordWizardProps {
  api: ForgotPasswordApi;
  onSuccess: (message: string) => void;
  normalizeNationalCode?: (value: string) => string;
}

const STEP_LABELS: Record<ForgotStep, string> = {
  identity: "کد ملی و کپچا",
  otp: "کد تأیید",
  password: "رمز جدید",
};

export function ForgotPasswordWizard({
  api,
  onSuccess,
  normalizeNationalCode = (value) => value.replace(/\D/g, "").slice(0, 10),
}: ForgotPasswordWizardProps) {
  const [step, setStep] = useState<ForgotStep>("identity");
  const [nationalCode, setNationalCode] = useState("");
  const [isForeign, setIsForeign] = useState(false);
  const [captchaKey, setCaptchaKey] = useState("");
  const [captchaQuestion, setCaptchaQuestion] = useState("");
  const [captchaAnswer, setCaptchaAnswer] = useState("");
  const [otp, setOtp] = useState("");
  const [password, setPassword] = useState("");
  const [passwordConfirmation, setPasswordConfirmation] = useState("");
  const [loading, setLoading] = useState(false);
  const [captchaLoading, setCaptchaLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [info, setInfo] = useState<string | null>(null);

  const loadCaptcha = useCallback(async () => {
    setCaptchaLoading(true);
    try {
      const data = await api.fetchCaptcha();
      setCaptchaKey(data.key);
      setCaptchaQuestion(data.question);
      setCaptchaAnswer("");
    } catch (err) {
      setError(err instanceof Error ? err.message : "خطا در دریافت کپچا");
    } finally {
      setCaptchaLoading(false);
    }
  }, [api]);

  useEffect(() => {
    void loadCaptcha();
  }, [loadCaptcha]);

  const normalizedCode = isForeign
    ? nationalCode.trim().slice(0, MAX_FOREIGN_IDENTIFIER_LENGTH)
    : normalizeNationalCode(nationalCode);

  const goBack = () => {
    setError(null);
    setInfo(null);
    if (step === "otp") {
      setStep("identity");
      setOtp("");
      void loadCaptcha();
      return;
    }
    if (step === "password") {
      setStep("otp");
      setPassword("");
      setPasswordConfirmation("");
    }
  };

  const submitIdentity = async (event: FormEvent) => {
    event.preventDefault();
    setError(null);
    setInfo(null);

    if (!isCompletePersonIdentifier(normalizedCode, isForeign)) {
      setError(isForeign ? "شناسه اتباع الزامی است." : validationMessages.nationalCodeLength);
      return;
    }
    if (!isForeign && !isValidNationalCode(normalizedCode)) {
      setError(validationMessages.nationalCodeInvalid);
      return;
    }
    if (!captchaAnswer.trim()) {
      setError(validationMessages.captchaRequired);
      return;
    }

    setLoading(true);
    try {
      const message = await api.forgotPassword({
        national_code: normalizedCode,
        is_foreign_national: isForeign,
        captcha_key: captchaKey,
        captcha_answer: captchaAnswer.trim(),
      });
      setInfo(message);
      setStep("otp");
    } catch (err) {
      setError(err instanceof Error ? err.message : "خطا در ارسال کد تأیید");
      void loadCaptcha();
    } finally {
      setLoading(false);
    }
  };

  const submitOtp = async (event: FormEvent) => {
    event.preventDefault();
    setError(null);
    setInfo(null);

    if (!otp.trim()) {
      setError(validationMessages.otpRequired);
      return;
    }

    setLoading(true);
    try {
      const message = await api.verifyForgotOtp({
        national_code: normalizedCode,
        otp: otp.trim(),
      });
      setInfo(message);
      setStep("password");
    } catch (err) {
      setError(err instanceof Error ? err.message : "کد تأیید نامعتبر است");
    } finally {
      setLoading(false);
    }
  };

  const submitPassword = async (event: FormEvent) => {
    event.preventDefault();
    setError(null);
    setInfo(null);

    if (password.length < 8) {
      setError(validationMessages.minLength("رمز عبور", 8));
      return;
    }
    if (password !== passwordConfirmation) {
      setError(validationMessages.passwordMismatch);
      return;
    }

    setLoading(true);
    try {
      const message = await api.resetPassword({
        national_code: normalizedCode,
        password,
        password_confirmation: passwordConfirmation,
      });
      onSuccess(message);
    } catch (err) {
      setError(err instanceof Error ? err.message : "خطا در تغییر رمز عبور");
    } finally {
      setLoading(false);
    }
  };

  const stepIndex = step === "identity" ? 1 : step === "otp" ? 2 : 3;

  return (
    <div>
      <div className="mb-4 flex items-center justify-between text-xs text-[var(--muted)]">
        <span>
          مرحله {stepIndex} از ۳ — {STEP_LABELS[step]}
        </span>
        {step !== "identity" ? (
          <button type="button" className="font-medium text-primary hover:underline" onClick={goBack}>
            ← بازگشت
          </button>
        ) : null}
      </div>

      {error ? (
        <div className="mb-4">
          <Alert tone="error">{error}</Alert>
        </div>
      ) : null}
      {info ? (
        <div className="mb-4">
          <Alert tone="success">{info}</Alert>
        </div>
      ) : null}

      {step === "identity" ? (
        <form onSubmit={submitIdentity}>
          <label className="mb-3 flex items-center gap-2 text-sm">
            <input
              type="checkbox"
              checked={isForeign}
              onChange={(e) => {
                setIsForeign(e.target.checked);
                setNationalCode((current) => sanitizePersonIdentifier(current, e.target.checked));
              }}
            />
            اتباع هستم
          </label>
          <Field label={isForeign ? "شناسه اتباع" : "کد ملی"}>
            <Input
              inputMode={isForeign ? "text" : "numeric"}
              autoComplete="username"
              maxLength={isForeign ? MAX_FOREIGN_IDENTIFIER_LENGTH : 10}
              value={nationalCode}
              onChange={(e) => setNationalCode(sanitizePersonIdentifier(e.target.value, isForeign))}
              required
            />
          </Field>

          <div className="mt-4">
            <Field label="کپچا">
              <div className="mb-2 flex items-center justify-between rounded-xl border border-[var(--border)] bg-slate-50 px-3 py-2 text-sm font-semibold">
                <span>{captchaQuestion || "..."}</span>
                <Button
                  type="button"
                  variant="secondary"
                  loading={captchaLoading}
                  onClick={() => void loadCaptcha()}
                >
                  تازه‌سازی
                </Button>
              </div>
              <Input
                inputMode="numeric"
                value={captchaAnswer}
                onChange={(e) => setCaptchaAnswer(e.target.value.replace(/\D/g, "").slice(0, 10))}
                placeholder="پاسخ را وارد کنید"
                required
              />
            </Field>
          </div>

          <Button type="submit" block loading={loading} className="mt-5">
            ادامه
          </Button>
        </form>
      ) : null}

      {step === "otp" ? (
        <form onSubmit={submitOtp}>
          <Field label="کد ملی">
            <Input value={normalizedCode} disabled />
          </Field>
          <div className="mt-4">
            <Field label="رمز یک‌بارمصرف (OTP)">
              <Input
                inputMode="numeric"
                autoComplete="one-time-code"
                value={otp}
                onChange={(e) => setOtp(e.target.value.replace(/\D/g, "").slice(0, 8))}
                required
              />
            </Field>
          </div>
          <Button type="submit" block loading={loading} className="mt-5">
            تأیید کد
          </Button>
        </form>
      ) : null}

      {step === "password" ? (
        <form onSubmit={submitPassword}>
          <Field label="کد ملی">
            <Input value={normalizedCode} disabled />
          </Field>
          <div className="mt-4">
            <Field label="رمز عبور جدید">
              <Input
                type="password"
                autoComplete="new-password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                required
                minLength={8}
              />
            </Field>
          </div>
          <div className="mt-4">
            <Field label="تکرار رمز عبور جدید">
              <Input
                type="password"
                autoComplete="new-password"
                value={passwordConfirmation}
                onChange={(e) => setPasswordConfirmation(e.target.value)}
                required
                minLength={8}
              />
            </Field>
          </div>
          <Button type="submit" block loading={loading} className="mt-5">
            ذخیره رمز جدید
          </Button>
        </form>
      ) : null}
    </div>
  );
}
