import React, { useEffect, useMemo, useRef, useState } from "react";
import Logo from "../assets/logo.png";
import { useForm } from "react-hook-form";
import { useNavigate } from "react-router";
import { useToast } from "../components/ToastProvider";
import { Axiosinstance } from "../services/auth/Axiosinstance";

import BrandPanel from "../components/auth/BrandPanel";
import FloatingInput from "../components/auth/FloatingInput";
import PasswordField from "../components/auth/PasswordField";
import AuthActions from "../components/auth/AuthActions";
import AuthLinkButton from "../components/auth/AuthLinkButton";
import OtpResetStoreOnly from "../components/auth/OtpResetStoreOnly";

/* ---------------- helpers ---------------- */
function calcRules(p = "") {
  const s = String(p || "");
  return {
    minLen: s.length >= 8,
    upper: /[A-Z]/.test(s),
    symbol: /[^A-Za-z0-9]/.test(s),
  };
}

function calcStrength(p = "") {
  const r = calcRules(p);
  const score = [r.minLen, r.upper, r.symbol].filter(Boolean).length;
  if (!p) return { level: 0, label: "—", percent: 0, rules: r };
  if (score <= 1) return { level: 1, label: "ضعیف", percent: 34, rules: r };
  if (score === 2) return { level: 2, label: "متوسط", percent: 67, rules: r };
  return { level: 3, label: "قوی", percent: 100, rules: r };
}

const STEP = {
  PHONE: "PHONE",
  CODE: "CODE",
  PASSWORD: "PASSWORD",
};

export default function ForgotPassword() {
  const navigate = useNavigate();
  const { success, error: toastError, info, warning } = useToast();

  const CHANNEL = "sms";

  const {
    register,
    handleSubmit,
    formState: { errors, isSubmitting },
    watch,
    setError,
    clearErrors,
    getValues,
  } = useForm({
    mode: "onSubmit",
    defaultValues: {
      target: "",
      new_password: "",
      confirmPassword: "",
    },
  });

  const targetValue = watch("target");
  const newPassValue = watch("new_password");
  const confirmPassValue = watch("confirmPassword");
  const strength = useMemo(() => calcStrength(newPassValue), [newPassValue]);

  const [step, setStep] = useState(STEP.PHONE);
  const [secondsLeft, setSecondsLeft] = useState(0);

  // ✅ فقط نگه‌داری کد
  const [cachedCode, setCachedCode] = useState("");
  const [codeError, setCodeError] = useState("");

  const passWrapRef = useRef(null);
  const [showPassTip, setShowPassTip] = useState(false);

  const canResend = step === STEP.CODE && secondsLeft === 0;

  useEffect(() => {
    if (step !== STEP.CODE) return;
    if (secondsLeft <= 0) return;
    const t = setInterval(() => setSecondsLeft((p) => (p > 0 ? p - 1 : 0)), 1000);
    return () => clearInterval(t);
  }, [step, secondsLeft]);

  const formatTime = (totalSeconds) => {
    const m = Math.floor(totalSeconds / 60);
    const s = totalSeconds % 60;
    return `${m}:${String(s).padStart(2, "0")}`;
  };

  const getErrorMessage = (error) =>
    error?.response?.data?.detail || error?.response?.data?.message || (typeof error?.response?.data === "string" ? error.response.data : null) || "مشکلی پیش آمد. لطفاً دوباره تلاش کنید.";

  const requestResetCode = async (target) => {
    return Axiosinstance.post("accounts/request-code/", {
      channel: CHANNEL,
      target,
      purpose: "reset_password",
    });
  };

  const confirmResetPassword = async ({ target, code, new_password }) => {
    return Axiosinstance.post("accounts/reset-password/confirm/", {
      channel: CHANNEL,
      target,
      code,
      new_password,
    });
  };

  const isPasswordMatch = Boolean(newPassValue && confirmPassValue) && newPassValue === confirmPassValue;

  const canSubmitPhone = Boolean(targetValue);
  const canSubmitCode = Boolean(String(cachedCode || "").trim()); // ✅ فقط نگه‌داری
  const canSubmitPassword = Boolean(newPassValue && confirmPassValue && isPasswordMatch);

  const onSubmit = async (formData) => {
    try {
      if (step === STEP.PHONE) {
        if (!formData.target) {
          setError("target", { type: "required", message: "شماره تماس را وارد کنید" });
          return;
        }

        await requestResetCode(formData.target);

        setStep(STEP.CODE);
        setSecondsLeft(120);
        setCachedCode("");
        setCodeError("");
        clearErrors("target");

        info("کد تأیید برای تغییر رمز عبور ارسال شد.", { title: "ارسال کد" });
        return;
      }

      if (step === STEP.CODE) {
        const code = String(cachedCode || "").trim();
        if (!code) {
          setCodeError("کد تایید را وارد کنید");
          return;
        }

        // ✅ برو مرحله رمز
        setStep(STEP.PASSWORD);
        info("کد ثبت شد. حالا رمز جدید را وارد کنید.", { title: "مرحله بعد" });
        return;
      }

      if (step === STEP.PASSWORD) {
        if (!cachedCode) {
          warning("کد تایید ثبت نشده. دوباره وارد کنید.", { title: "خطا" });
          setStep(STEP.CODE);
          return;
        }

        if (!isPasswordMatch) {
          setError("confirmPassword", {
            type: "validate",
            message: "رمز عبور و تکرار آن یکسان نیستند",
          });
          return;
        }

        await confirmResetPassword({
          target: formData.target,
          code: cachedCode,
          new_password: formData.new_password,
        });

        success("رمز عبور با موفقیت تغییر کرد. حالا می‌توانید وارد شوید.", { title: "انجام شد ✅" });
        navigate("/auth/login");
      }
    } catch (error) {
      toastError(getErrorMessage(error), { title: "خطا" });
    }
  };

  const handleResendCode = async () => {
    if (!canResend) return;

    const t = String(getValues("target") || "").trim();
    if (!t) {
      warning("شماره تماس نامعتبر است.", { title: "ارسال مجدد" });
      return;
    }

    try {
      await requestResetCode(t);
      setSecondsLeft(120);
      success("کد جدید ارسال شد.", { title: "ارسال مجدد" });
    } catch (error) {
      toastError(getErrorMessage(error), { title: "ارسال مجدد" });
    }
  };

  const primaryText = step === STEP.PHONE ? "ارسال کد تایید" : step === STEP.CODE ? "ثبت کد" : "تغییر رمز";

  const canSubmit = step === STEP.PHONE ? canSubmitPhone : step === STEP.CODE ? canSubmitCode : canSubmitPassword;

  return (
    <div className="flex md:flex-wrap flex-wrap-reverse w-full">
      <div className="bg-[#16325B] md:w-1/2 min-h-[calc(100vh-160px)] w-full md:rounded-l-4xl rounded-4xl md:rounded-r-none">
        <div className="flex justify-center md:min-h-[700px] items-center p-9 md:h-screen">
          <div className="xl:w-1/2 lg:w-2/3 w-full max-w-80 grid items-center">
            <h3 className="font-bold text-3xl text-center text-white">بازیابی رمز عبور</h3>

            {step === STEP.PHONE && <p className="font-medium text-base text-center text-white/75">شماره تماس را وارد کنید تا کد تأیید ارسال شود</p>}
            {step === STEP.CODE && <p className="font-medium text-base text-center text-white/75">کد تایید را وارد کنید</p>}
            {step === STEP.PASSWORD && <p className="font-medium text-base text-center text-white/75">رمز جدید را وارد کنید تا تغییر رمز انجام شود</p>}

            <form onSubmit={handleSubmit(onSubmit)}>
              {step === STEP.PHONE && <FloatingInput label="شماره تماس" type="tel" name="target" register={register} rules={{ required: "شماره تماس را وارد کنید" }} error={errors.target?.message} />}

              {step === STEP.CODE && (
                <>
                  <OtpResetStoreOnly
                    length={6}
                    secondsLeft={secondsLeft}
                    canResend={canResend}
                    onResend={handleResendCode}
                    formatTime={formatTime}
                    label="کد تایید"
                    errorText={codeError}
                    onCodeChange={(c) => {
                      setCachedCode(c);
                      if (c) setCodeError("");
                    }}
                  />

                  <div className="mt-2 flex items-center justify-between">
                    <AuthLinkButton
                      onClick={() => {
                        setCachedCode("");
                        setCodeError("");
                        setStep(STEP.PHONE);
                        setSecondsLeft(0);
                      }}
                    >
                      تغییر شماره
                    </AuthLinkButton>
                  </div>
                </>
              )}

              {step === STEP.PASSWORD && (
                <>
                  <PasswordField
                    label="رمز عبور جدید"
                    reg={register("new_password", {
                      required: "رمز عبور جدید را وارد کنید",
                      validate: (v) => {
                        const r = calcRules(v);
                        if (!r.minLen) return "حداقل ۸ کاراکتر";
                        if (!r.upper) return "حداقل ۱ حرف بزرگ (A-Z)";
                        if (!r.symbol) return "حداقل ۱ علامت (!@#...)";
                        return true;
                      },
                    })}
                    showTip={showPassTip}
                    setShowTip={setShowPassTip}
                    rules={strength.rules}
                    strength={strength}
                    errorText={errors.new_password?.message}
                    wrapperRef={passWrapRef}
                  />

                  <FloatingInput
                    label="تکرار رمز عبور جدید"
                    type="password"
                    name="confirmPassword"
                    register={register}
                    rules={{
                      required: "تکرار رمز عبور را وارد کنید",
                      validate: (v) => v === newPassValue || "رمز عبور و تکرار آن یکسان نیستند",
                    }}
                    error={errors.confirmPassword?.message}
                  />
                </>
              )}

              <AuthActions
                isCodeStep={step !== STEP.PHONE}
                isSubmitting={isSubmitting}
                canSubmitStep1={canSubmit}
                primaryText={primaryText}
                secondaryText="برگشت به ورود"
                onSecondary={() => navigate("/auth/login")}
                showSecondary={true}
              />
            </form>
          </div>
        </div>
      </div>

      <BrandPanel logoSrc={Logo} />
    </div>
  );
}
