// src/pages/Register.jsx
import React, { useEffect, useMemo, useRef, useState } from "react";
import Logo from "../assets/logo.png";
import { useForm } from "react-hook-form";
import { useRegister, useVerify, useOTP, useLogin } from "../services/auth/auth";
import { useNavigate } from "react-router";
import { useToast } from "../components/ToastProvider";

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

import { passwordRulesStatus, passwordStrength } from "../utils/password";

function Register() {
  const navigate = useNavigate();

  const { mutateAsync: registerUser } = useRegister();
  const { mutateAsync: verifyCode } = useVerify();
  const { mutateAsync: otprequest } = useOTP();
  const { mutateAsync: loginUser } = useLogin();

  const { success, error: toastError, info, warning } = useToast();

  const {
    register,
    handleSubmit,
    formState: { errors, isSubmitting },
    watch,
    setError,
    clearErrors,
    setValue,
    trigger,
    setFocus,
  } = useForm({
    mode: "onChange",
    defaultValues: {
      username: "",
      email: "",
      phone: "",
      password: "",
      confirmPassword: "",
      code: "",
    },
  });

  const passwordValue = watch("password");
  const confirmPasswordValue = watch("confirmPassword");
  const phoneValue = watch("phone");
  const usernameValue = watch("username");

  const rules = useMemo(() => passwordRulesStatus(passwordValue || ""), [passwordValue]);
  const strength = useMemo(() => passwordStrength(passwordValue || ""), [passwordValue]);

  const isPasswordMatch = Boolean(passwordValue) && passwordValue === confirmPasswordValue;
  const isPasswordValid = rules.minLen && rules.upper && rules.symbol;
  const canSubmitStep1 = Boolean(passwordValue && confirmPasswordValue) && isPasswordMatch && isPasswordValid;

  const [isCodeStep, setIsCodeStep] = useState(false);
  const [secondsLeft, setSecondsLeft] = useState(0);
  const canResend = secondsLeft === 0 && isCodeStep;

  useEffect(() => {
    let interval;
    if (isCodeStep && secondsLeft > 0) {
      interval = setInterval(() => setSecondsLeft((prev) => prev - 1), 1000);
    }
    return () => interval && clearInterval(interval);
  }, [isCodeStep, secondsLeft]);

  // Tooltip کنترل
  const [showPwTip, setShowPwTip] = useState(false);
  const pwWrapRef = useRef(null);

  useEffect(() => {
    if (!showPwTip) return;
    const onDown = (e) => {
      if (!pwWrapRef.current) return;
      if (pwWrapRef.current.contains(e.target)) return;
      setShowPwTip(false);
    };
    document.addEventListener("pointerdown", onDown);
    return () => document.removeEventListener("pointerdown", onDown);
  }, [showPwTip]);

  // ارور پسورد اگر قوانین پاس نشه
  useEffect(() => {
    if (!passwordValue) {
      clearErrors("password");
      return;
    }
    if (!isPasswordValid) {
      setError("password", {
        type: "validate",
        message: "رمز عبور باید حداقل ۸ کاراکتر، شامل حداقل ۱ حرف بزرگ و ۱ علامت باشد.",
      });
    } else {
      if (errors.password?.type === "validate") clearErrors("password");
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [passwordValue, isPasswordValid]);

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

  // ---------- NEW: error helpers ----------
  const normalizeToText = (v) => {
    if (!v) return "";
    if (Array.isArray(v)) return v.filter(Boolean).join("، ");
    if (typeof v === "string") return v;
    if (typeof v === "object") {
      // sometimes backend returns {detail: "..."} inside fields (rare)
      if (typeof v.detail === "string") return v.detail;
    }
    return "";
  };

  const applyBackendFieldErrors = (err, { isCodeStepNow }) => {
    const data = err?.response?.data;
    if (!data || typeof data !== "object") return false;

    let applied = false;

    // map common DRF field errors
    const fieldMap = {
      username: "username",
      email: "email",
      phone: "phone",
      mobile: "phone",
      contact: "phone",
      code: "code",
      otp: "code",
    };

    Object.keys(fieldMap).forEach((k) => {
      if (data[k]) {
        const msg = normalizeToText(data[k]);
        if (msg) {
          setError(fieldMap[k], { type: "server", message: msg });
          applied = true;
        }
      }
    });

    // sometimes errors are non-field
    const nonField =
      normalizeToText(data.non_field_errors) ||
      normalizeToText(data.detail) ||
      normalizeToText(data.message);

    // اگر مرحله کد هست و بک‌اند ارور رو به هدف/کد چسبونده
    if (isCodeStepNow) {
      const codeLike =
        normalizeToText(data.code) ||
        normalizeToText(data.otp) ||
        normalizeToText(data.target) ||
        normalizeToText(data.purpose);

      if (codeLike) {
        setError("code", { type: "server", message: codeLike });
        applied = true;
      }
    }

    // اگر فقط non-field داشت، applied رو true نکنیم تا toast زده بشه
    return applied;
  };

  const pickBestToastMessage = (err) => {
    const data = err?.response?.data;

    // اگر آبجکت فیلدها بود، یک خلاصه انسانی بساز
    if (data && typeof data === "object" && !Array.isArray(data)) {
      const parts = [];
      if (data.username) parts.push(`${normalizeToText(data.username)}`);
      if (data.email) parts.push(`${normalizeToText(data.email)}`);
      if (data.phone || data.mobile || data.contact) parts.push(`${normalizeToText(data.phone || data.mobile || data.contact)}`);
      if (data.code || data.otp) parts.push(`${normalizeToText(data.code || data.otp)}`);

      const nonField =
        normalizeToText(data.non_field_errors) ||
        normalizeToText(data.detail) ||
        normalizeToText(data.message);

      if (parts.length) return parts.join("\n");
      if (nonField) return nonField;
    }

    // fallback
    return "عملیات با خطا مواجه شد. لطفاً دوباره تلاش کنید.";
  };

  const clearServerErrorsForStep = (stepIsCode) => {
    // پاک کردن خطاهای سرور برای تجربه بهتر
    if (!stepIsCode) {
      ["username", "email", "phone"].forEach((f) => {
        if (errors?.[f]?.type === "server") clearErrors(f);
      });
    } else {
      if (errors?.code?.type === "server") clearErrors("code");
    }
  };

  const onSubmit = async (formData) => {
    try {
      // قبل از ارسال، server-errors های همان مرحله پاک شود
      clearServerErrorsForStep(isCodeStep);

      if (!isCodeStep) {
        const { code, confirmPassword, ...rest } = formData;

        if (!isPasswordValid) {
          warning("رمز عبور شرایط لازم را ندارد.", { title: "ثبت نام" });
          return;
        }
        if (formData.password !== formData.confirmPassword) {
          warning("رمز عبور و تکرار آن یکسان نیستند.", { title: "ثبت نام" });
          return;
        }

        await registerUser(rest);

        setIsCodeStep(true);
        setSecondsLeft(120);
        info("کد تأیید به شماره تماس شما ارسال شد.", { title: "ارسال کد" });
        // فوکوس روی اولین باکس OTP
        setTimeout(() => setFocus("code"), 0);
      } else {
        await verifyCode({
          channel: "sms",
          target: formData.phone,
          code: formData.code,
          purpose: "signup",
        });

        await loginUser({
          username: usernameValue,
          password: passwordValue,
        });

        success("حساب شما فعال شد و وارد شدید.", { title: "خوش آمدید 🎉" });
        navigate("/home");
      }
    } catch (err) {
      // 1) اول تلاش کن خطاهای فیلدی رو روی فرم بنشونی
      const applied = applyBackendFieldErrors(err, { isCodeStepNow: isCodeStep });

      // اگر فیلدی بود، بهتره فوکوس هم بدیم
      if (applied) {
        // اولویت فوکوس: username/email در مرحله ۱، code در مرحله ۲
        if (!isCodeStep) {
          if (err?.response?.data?.username) setFocus("username");
          else if (err?.response?.data?.email) setFocus("email");
          else if (err?.response?.data?.phone || err?.response?.data?.mobile || err?.response?.data?.contact) setFocus("phone");
        } else {
          setFocus("code");
        }
      }

      // 2) toast هم بزن (حتی اگر applied شد، برای اینکه کاربر سریع بفهمه چی شده)
      toastError(pickBestToastMessage(err), { title: "خطا" });
    }
  };

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

    if (!phoneValue) {
      warning("شماره تماس نامعتبر است.", { title: "ارسال مجدد" });
      return;
    }

    try {
      await otprequest({
        channel: "sms",
        target: phoneValue,
        purpose: "signup",
      });

      setSecondsLeft(120);
      success("کد جدید ارسال شد.", { title: "ارسال مجدد" });
    } catch (err) {
      // اگر سرور گفت شماره مشکل دارد، روی همان فیلد بنشیند
      applyBackendFieldErrors(err, { isCodeStepNow: true });
      toastError(pickBestToastMessage(err), { title: "ارسال مجدد" });
    }
  };

  // خیلی مهم: خروجی register پسورد رو جدا می‌گیریم تا PasswordField درست کار کنه
  const pwReg = register("password", { required: true });

  return (
    <div className="flex md:flex-wrap flex-wrap-reverse w-full">
      {/* Left */}
      <div className="bg-[#16325B] md:w-1/2 w-full min-h-[calc(100vh-160px)] md:rounded-l-4xl rounded-4xl md:rounded-r-none">
        <div className="flex justify-center 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>
            <p className="font-medium text-base text-center text-white/75">برای ثبت‌نام اطلاعات زیر را وارد کنید</p>

            <form onSubmit={handleSubmit(onSubmit)}>
              {!isCodeStep && (
                <>
                  <FloatingInput
                    label="نام کاربری"
                    name="username"
                    type="text"
                    register={register}
                    rules={{ required: true }}
                    error={
                      (errors.username?.type === "required" && "نام کاربری خود را وارد کنید") ||
                      errors.username?.message ||
                      ""
                    }
                  />

                  <FloatingInput
                    label="ایمیل"
                    name="email"
                    type="email"
                    register={register}
                    rules={{ required: true }}
                    error={
                      (errors.email?.type === "required" && "ایمیل خود را وارد کنید") ||
                      errors.email?.message ||
                      ""
                    }
                  />

                  <FloatingInput
                    label="شماره تماس"
                    name="phone"
                    type="tel"
                    register={register}
                    rules={{ required: true }}
                    inputProps={{ maxLength: 11 }}
                    error={
                      (errors.phone?.type === "required" && "شماره تماس را وارد کنید") ||
                      errors.phone?.message ||
                      ""
                    }
                  />

                  <PasswordField
                    reg={pwReg}
                    wrapperRef={pwWrapRef}
                    showTip={showPwTip}
                    setShowTip={setShowPwTip}
                    rules={rules}
                    strength={strength}
                    errorText={
                      (errors.password?.type === "required" && "رمزعبور را وارد کنید") ||
                      errors.password?.message ||
                      ""
                    }
                  />

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

              {isCodeStep && (
                <OtpSection
                  register={register}
                  errors={errors}
                  secondsLeft={secondsLeft}
                  canResend={canResend}
                  onResend={handleResendCode}
                  formatTime={formatTime}
                  setValue={setValue}
                  trigger={trigger}
                  focusFirst={true}
                />
              )}

              <AuthActions
                isCodeStep={isCodeStep}
                isSubmitting={isSubmitting}
                canSubmitStep1={canSubmitStep1}
                onGoLogin={() => navigate("/auth/login")}
              />
            </form>
          </div>
        </div>
      </div>

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

export default Register;
