import React, { useCallback, useEffect, useMemo, useState } from "react";
import { Axiosinstance } from "../services/auth/Axiosinstance";
import { useToast } from "../components/ToastProvider";
import { Button, PageShell, PageActions, Grid2, cn } from "../components/ui";
import { LuRefreshCcw } from "react-icons/lu";

import useCooldownAction from "../hooks/useCooldownAction";
import useCountdownTimer from "../hooks/useCountdownTimer";

import ChangePasswordFormCard from "../components/security/ChangePasswordFormCard";
import SecurityStatusCard from "../components/security/SecurityStatusCard";
import TwoFactorModal from "../components/security/TwoFactorModal";

import { getErrMsg, toFaDigits } from "../utils/account";

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

  // ===================== Form =====================
  const [oldPassword, setOldPassword] = useState("");
  const [newPassword, setNewPassword] = useState("");
  const [confirmNew, setConfirmNew] = useState("");

  // ===================== Me =====================
  const [me, setMe] = useState(null);
  const [meLoading, setMeLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);

  // ===================== Change Password =====================
  const [saving, setSaving] = useState(false);

  // ===================== 2FA =====================
  const [twofaOpen, setTwofaOpen] = useState(false);
  const [twofaChannel, setTwofaChannel] = useState("sms"); // sms | email (email disabled)
  const [twofaCode, setTwofaCode] = useState("");
  const [enabling2fa, setEnabling2fa] = useState(false);
  const [confirming2fa, setConfirming2fa] = useState(false);
  const [disabling2fa, setDisabling2fa] = useState(false);

  // resend timer (2min)
  const {
    timer: twofaTimer,
    start: startTwofaTimer,
    reset: resetTwofaTimer,
  } = useCountdownTimer();

  const is2faEnabled = !!me?.two_factor_enabled;
  const twoFAStatusChannel = me?.two_factor_channel || "";

  const anyBusy =
    meLoading ||
    refreshing ||
    saving ||
    enabling2fa ||
    confirming2fa ||
    disabling2fa;

  // ===================== Fetch Me =====================
  const fetchMe = useCallback(
    async ({ silent = false, mode = "init" } = {}) => {
      if (mode === "refresh") setRefreshing(true);
      else setMeLoading(true);

      try {
        const res = await Axiosinstance.get("accounts/me/");
        setMe(res?.data || null);
        if (!silent) info("اطلاعات امنیتی بروزرسانی شد.", { title: "امنیت" });
      } catch (e) {
        setMe(null);
        if (!silent) toastError(getErrMsg(e, "خطا در دریافت اطلاعات حساب"), { title: "امنیت" });
      } finally {
        if (mode === "refresh") setRefreshing(false);
        else setMeLoading(false);
      }
    },
    [info, toastError]
  );

  useEffect(() => {
    fetchMe({ silent: true, mode: "init" });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // ===================== Cooldown Actions =====================
  const refreshAction = useCooldownAction({
    cooldownMs: 3000,
    title: "امنیت",
    isBusy: anyBusy,
    busyMessage: "در حال بروزرسانی...",
    busyToast: info,
    onRun: async () => fetchMe({ silent: false, mode: "refresh" }),
  });

  const validationError = useMemo(() => {
    if (!oldPassword.trim() || !newPassword.trim() || !confirmNew.trim())
      return "همه فیلدها الزامی هستند.";
    if (newPassword.length < 8) return "رمز جدید باید حداقل ۸ کاراکتر باشد.";
    if (newPassword !== confirmNew) return "رمز جدید با تکرار آن یکسان نیست.";
    if (oldPassword === newPassword) return "رمز جدید نباید با رمز قبلی یکی باشد.";
    return "";
  }, [oldPassword, newPassword, confirmNew]);

  const changePassword = async () => {
    if (validationError) {
      warning(validationError, { title: "تغییر رمز" });
      return;
    }

    setSaving(true);
    try {
      await Axiosinstance.post("accounts/change-password/", {
        old_password: oldPassword,
        new_password: newPassword,
      });

      success("رمز عبور با موفقیت تغییر کرد ✅", { title: "تغییر رمز" });
      setOldPassword("");
      setNewPassword("");
      setConfirmNew("");
    } catch (e) {
      toastError(getErrMsg(e, "خطا در تغییر رمز عبور"), { title: "تغییر رمز" });
    } finally {
      setSaving(false);
    }
  };

  const saveAction = useCooldownAction({
    cooldownMs: 3000,
    title: "تغییر رمز",
    isBusy: anyBusy,
    busyMessage: "در حال تغییر رمز...",
    busyToast: info,
    onRun: changePassword,
  });

  // 2FA gate action (cooldown 2.5s)
  const twofaGate = useCooldownAction({
    cooldownMs: 2500,
    title: "ورود دو مرحله‌ای",
    isBusy: anyBusy,
    busyMessage: "در حال انجام عملیات 2FA...",
    busyToast: info,
    onRun: async () => {}, // فقط برای cooldown/disabled/leftMs
  });

  // ===================== 2FA handlers =====================
  const open2faModal = () => {
    setTwofaCode("");
    setTwofaChannel("sms");
    setTwofaOpen(true);
  };

  const close2faModal = () => {
    if (enabling2fa || confirming2fa || disabling2fa) return;
    setTwofaOpen(false);
    setTwofaCode("");
  };

  const enable2fa = async () => {
    // resend lock 2min
    if (twofaTimer > 0) {
      info(`برای ارسال مجدد کد، ${toFaDigits(twofaTimer)} ثانیه صبر کن.`, {
        title: "ورود دو مرحله‌ای",
      });
      return;
    }

    if (twofaGate.disabled) {
      // cooldown/busy message already handled in hook
      twofaGate.run?.();
      return;
    }

    // email disabled
    if (twofaChannel === "email") {
      warning("فعلاً فعالسازی با ایمیل غیرفعال است.", { title: "ورود دو مرحله‌ای" });
      return;
    }

    setEnabling2fa(true);
    try {
      // trigger cooldown stamp
      twofaGate.run?.();

      await Axiosinstance.post("accounts/2fa/enable/", { channel: "sms" });
      success("کد فعالسازی 2FA ارسال شد ✅", { title: "ورود دو مرحله‌ای" });

      startTwofaTimer(120);
    } catch (e) {
      toastError(getErrMsg(e, "خطا در شروع فعالسازی 2FA"), { title: "ورود دو مرحله‌ای" });
    } finally {
      setEnabling2fa(false);
    }
  };

  const confirm2fa = async () => {
    const c = String(twofaCode || "").trim();
    if (!c) {
      warning("کد را وارد کنید.", { title: "ورود دو مرحله‌ای" });
      return;
    }

    if (twofaGate.disabled) {
      twofaGate.run?.();
      return;
    }

    setConfirming2fa(true);
    try {
      twofaGate.run?.();

      const res = await Axiosinstance.post("accounts/2fa/confirm/", { code: c });
      success(res?.data?.detail || "ورود دومرحله‌ای با موفقیت فعال شد ✅", {
        title: "ورود دو مرحله‌ای",
      });

      setTwofaOpen(false);
      setTwofaCode("");
      resetTwofaTimer();

      await fetchMe({ silent: true, mode: "refresh" });
    } catch (e) {
      toastError(getErrMsg(e, "کد وارد شده صحیح نیست یا منقضی شده است"), {
        title: "ورود دو مرحله‌ای",
      });
    } finally {
      setConfirming2fa(false);
    }
  };

  const disable2fa = async () => {
    if (twofaGate.disabled) {
      twofaGate.run?.();
      return;
    }

    setDisabling2fa(true);
    try {
      twofaGate.run?.();

      const res = await Axiosinstance.post("accounts/2fa/disable/");
      success(res?.data?.detail || "ورود دومرحله‌ای غیرفعال شد ✅", {
        title: "ورود دو مرحله‌ای",
      });

      resetTwofaTimer();
      await fetchMe({ silent: true, mode: "refresh" });
    } catch (e) {
      toastError(getErrMsg(e, "خطا در غیرفعال‌سازی 2FA"), { title: "ورود دو مرحله‌ای" });
    } finally {
      setDisabling2fa(false);
    }
  };

  return (
    <PageShell
      title="تنظیمات امنیتی"
      subtitle="تغییر رمزعبور و فعالسازی ورود دو مرحله‌ای"
      actions={
        <PageActions>
          <Button
            variant="outline"
            onClick={refreshAction.run}
            disabled={refreshAction.disabled}
            title={
              refreshAction.leftMs > 0
                ? `تا ${Math.ceil(refreshAction.leftMs / 1000)} ثانیه دیگر`
                : "به‌روزرسانی"
            }
            leftIcon={
              <LuRefreshCcw
                className={cn(
                  "w-4 h-4 text-[#43BEFF] dark:text-white",
                  refreshing ? "animate-spin" : ""
                )}
              />
            }
          >
            {refreshing ? "به‌روزرسانی..." : "به‌روزرسانی"}
          </Button>
        </PageActions>
      }
    >
      <Grid2>
        <ChangePasswordFormCard
          oldPassword={oldPassword}
          newPassword={newPassword}
          confirmNew={confirmNew}
          setOldPassword={setOldPassword}
          setNewPassword={setNewPassword}
          setConfirmNew={setConfirmNew}
          saving={saving}
          onSubmit={saveAction.run}
          disabled={saveAction.disabled}
          leftMs={saveAction.leftMs}
          validationError={validationError}
        />

        <SecurityStatusCard
          me={me}
          loading={meLoading}
          is2faEnabled={is2faEnabled}
          twoFAStatusChannel={twoFAStatusChannel}
          onOpen2fa={open2faModal}
          onDisable2fa={disable2fa}
          twofaDisabled={twofaGate.disabled}
          twofaLeftMs={twofaGate.leftMs}
        />
      </Grid2>

      <TwoFactorModal
        open={twofaOpen}
        onClose={close2faModal}
        is2faEnabled={is2faEnabled}
        twoFAStatusChannel={twoFAStatusChannel}
        channel={twofaChannel}
        setChannel={setTwofaChannel}
        code={twofaCode}
        setCode={setTwofaCode}
        timer={twofaTimer}
        enabling={enabling2fa}
        confirming={confirming2fa}
        twofaLeftMs={twofaGate.leftMs}
        onSend={enable2fa}
        onConfirm={confirm2fa}
      />
    </PageShell>
  );
} 