"use client";

import { FormEvent, useEffect, useState } from "react";
import { Alert } from "../components/Alert";
import { Button } from "../components/Button";
import { Field, Input } from "../components/Field";
import { validationMessages } from "../validation/messages";

export interface ChangePasswordApi {
  requestOtp: () => Promise<{ otp_sent?: boolean; retry_after?: number }>;
  changePassword: (input: {
    password: string;
    password_confirmation: string;
    otp: string;
  }) => Promise<string>;
}

const REASON_LABELS: Record<string, string> = {
  first_login: "در اولین ورود باید رمز عبور اولیه را تغییر دهید.",
  expired: "مدت اعتبار رمز عبور به پایان رسیده است.",
  admin_forced: "مدیر سیستم تغییر رمز عبور را برای شما الزامی کرده است.",
};

export function ChangePasswordForm({
  api,
  forced = false,
  reasons = [],
  onSuccess,
}: {
  api: ChangePasswordApi;
  forced?: boolean;
  reasons?: string[];
  onSuccess: (message: string) => void;
}) {
  const [password, setPassword] = useState("");
  const [passwordConfirmation, setPasswordConfirmation] = useState("");
  const [otp, setOtp] = useState("");
  const [step, setStep] = useState<"password" | "otp">("password");
  const [loading, setLoading] = useState(false);
  const [otpRetryAfter, setOtpRetryAfter] = useState(0);
  const [error, setError] = useState<string | null>(null);
  const [info, setInfo] = useState<string | null>(null);

  useEffect(() => {
    if (otpRetryAfter <= 0) return;
    const timer = window.setTimeout(() => setOtpRetryAfter((value) => Math.max(0, value - 1)), 1000);
    return () => window.clearTimeout(timer);
  }, [otpRetryAfter]);

  const localPasswordError = (): string | null => {
    if (password.length < 8 || !/\p{L}/u.test(password) || !/\d/u.test(password)) {
      return validationMessages.passwordRules;
    }
    if (password !== passwordConfirmation) {
      return validationMessages.passwordMismatch;
    }
    return null;
  };

  const sendOtp = async () => {
    const local = localPasswordError();
    if (local) {
      setError(local);
      return;
    }
    setLoading(true);
    setError(null);
    try {
      const data = await api.requestOtp();
      setStep("otp");
      setOtpRetryAfter(data.retry_after ?? 60);
      setInfo("کد تأیید به شماره همراه شما ارسال شد.");
    } catch (err) {
      setError(err instanceof Error ? err.message : "ارسال کد تأیید ناموفق بود.");
    } finally {
      setLoading(false);
    }
  };

  const submit = async (event: FormEvent) => {
    event.preventDefault();
    if (step === "password") {
      await sendOtp();
      return;
    }
    if (!otp.trim()) {
      setError(validationMessages.otpRequired);
      return;
    }
    setLoading(true);
    setError(null);
    try {
      const message = await api.changePassword({
        password,
        password_confirmation: passwordConfirmation,
        otp: otp.trim(),
      });
      onSuccess(message);
    } catch (err) {
      setError(err instanceof Error ? err.message : "تغییر رمز عبور ناموفق بود.");
    } finally {
      setLoading(false);
    }
  };

  return (
    <form onSubmit={(event) => void submit(event)} className="space-y-4">
      {forced ? (
        <Alert tone="warning">
          {reasons.map((reason) => REASON_LABELS[reason] ?? reason).join(" ")}
          {reasons.length === 0
            ? "برای ادامه استفاده از سامانه باید رمز عبور را تغییر دهید."
            : ""}
        </Alert>
      ) : null}
      {error ? <Alert tone="error">{error}</Alert> : null}
      {info ? <Alert tone="success">{info}</Alert> : null}

      <Field label="رمز عبور جدید">
        <Input
          type="password"
          value={password}
          onChange={(event) => setPassword(event.target.value)}
          autoComplete="new-password"
          disabled={step === "otp"}
        />
      </Field>
      <Field label="تکرار رمز عبور جدید">
        <Input
          type="password"
          value={passwordConfirmation}
          onChange={(event) => setPasswordConfirmation(event.target.value)}
          autoComplete="new-password"
          disabled={step === "otp"}
        />
      </Field>
      {step === "otp" ? (
        <Field label="کد تأیید">
          <Input
            value={otp}
            onChange={(event) => setOtp(event.target.value.replace(/\D/g, "").slice(0, 8))}
            inputMode="numeric"
            autoComplete="one-time-code"
          />
        </Field>
      ) : null}

      <p className="text-xs text-[var(--muted)]">{validationMessages.passwordRules}</p>

      <div className="flex flex-wrap gap-2">
        <Button type="submit" loading={loading} className="min-w-[8rem]">
          {step === "password" ? "ارسال کد تأیید" : "ثبت رمز جدید"}
        </Button>
        {step === "otp" ? (
          <Button
            type="button"
            variant="secondary"
            disabled={otpRetryAfter > 0 || loading}
            onClick={() => void sendOtp()}
          >
            {otpRetryAfter > 0 ? `ارسال مجدد (${otpRetryAfter})` : "ارسال مجدد کد"}
          </Button>
        ) : null}
      </div>
    </form>
  );
}
