"use client";

import { useEffect, useState } from "react";
import { toast } from "sonner";
import ConfirmModal from "../common/ConfirmModal";
import { EyeOffIcon, EyeViewIcon } from "../dashboard/icons";
import { useAppDispatch, useAppSelector } from "@/state/hooks";
import { changePasswordAdmin, resetChangePasswordStatus } from "@/state/auth";

function PasswordField({
  label,
  value,
  onChange,
  placeholder,
  error,
}: {
  label: string;
  value: string;
  onChange: (value: string) => void;
  placeholder?: string;
  error?: string | null;
}) {
  const [visible, setVisible] = useState(false);

  return (
    <div>
      <label className="mb-1.5 block text-[13px] font-medium text-[#344054]">{label}</label>
      <div className="relative">
        <input
          type={visible ? "text" : "password"}
          value={value}
          onChange={(e) => onChange(e.target.value)}
          placeholder={placeholder ?? "••••••••"}
          className={`h-10 w-full rounded-lg border px-3 pr-10 text-[13px] text-[#101828] outline-none placeholder:text-[#98A2B3] focus:border-[#1657D9] ${
            error ? "border-[#DC2626]" : "border-[#D0D5DD]"
          }`}
        />
        <button
          type="button"
          onClick={() => setVisible((prev) => !prev)}
          aria-label={visible ? `Hide ${label.toLowerCase()}` : `Show ${label.toLowerCase()}`}
          className="absolute right-3 top-1/2 -translate-y-1/2 text-[#98A2B3] transition-colors hover:text-[#344054] cursor-pointer"
        >
          {visible ? <EyeOffIcon /> : <EyeViewIcon />}
        </button>
      </div>
      {error && <p className="mt-1 text-[12px] text-[#DC2626]">{error}</p>}
    </div>
  );
}

export default function ChangePasswordModal({
  open,
  onClose,
  onSuccess,
}: {
  open: boolean;
  onClose: () => void;
  onSuccess: () => void;
}) {
  const dispatch = useAppDispatch();
  const { changePasswordStatus, changePasswordError } = useAppSelector(
    (state) => state.auth
  );

  const [currentPassword, setCurrentPassword] = useState("");
  const [newPassword, setNewPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [clientError, setClientError] = useState<string | null>(null);

  const loading = changePasswordStatus === "loading";

  useEffect(() => {
    if (open) {
      dispatch(resetChangePasswordStatus());
      setClientError(null);
    }
  }, [open, dispatch]);

  const handleClose = () => {
    setCurrentPassword("");
    setNewPassword("");
    setConfirmPassword("");
    setClientError(null);
    dispatch(resetChangePasswordStatus());
    onClose();
  };

  const hasMinLength = newPassword.length >= 8;
  const hasLetterAndNumber = /\d/.test(newPassword) && /[a-zA-Z]/.test(newPassword);
  const isPasswordValid = hasMinLength && hasLetterAndNumber;
  const passwordsMatch = newPassword === confirmPassword;

  const canSubmit =
    currentPassword.length > 0 &&
    newPassword.length > 0 &&
    confirmPassword.length > 0 &&
    isPasswordValid &&
    passwordsMatch;

  const handleConfirm = async () => {
    if (loading) return;

    if (!hasMinLength) {
      setClientError("Password must be at least 8 characters");
      return;
    }

    if (!hasLetterAndNumber) {
      setClientError("Password must contain at least 1 letter and 1 number");
      return;
    }

    if (!passwordsMatch) {
      setClientError("Passwords do not match");
      return;
    }

    setClientError(null);

    const resultAction = await dispatch(
      changePasswordAdmin({
        currentPassword,
        newPassword,
        confirmPassword,
      })
    );

    if (changePasswordAdmin.fulfilled.match(resultAction)) {
      toast.success(
        resultAction.payload.message || "Password changed successfully"
      );
      onSuccess();
      handleClose();
    } else if (changePasswordAdmin.rejected.match(resultAction)) {
      const errorMsg =
        (resultAction.payload as { message?: string })?.message ||
        "Failed to change password";
      toast.error(errorMsg);
    }
  };

  const confirmError =
    confirmPassword.length > 0 && !passwordsMatch ? "Passwords do not match" : null;

  const activeError = clientError || changePasswordError;

  return (
    <ConfirmModal
      open={open}
      title="Change Password"
      description="Change your password to keep your account secure. Make sure it's strong and unique."
      confirmLabel={loading ? "Updating..." : "Update Password"}
      confirmButtonClassName="bg-[#1657D9] hover:bg-[#1445B0] cursor-pointer"
      confirmDisabled={!canSubmit || loading}
      onClose={handleClose}
      onConfirm={handleConfirm}
      width="648px"
      showCloseIcon
      fullWidthButtons
    >
      <hr className="mt-4 border-[#E4E7EC]" />

      {activeError && (
        <div className="mt-4 rounded-lg bg-red-50 p-3 text-[13px] text-[#DC2626]">
          {activeError}
        </div>
      )}

      <div className="mt-4 flex flex-col gap-4">
        <PasswordField
          label="Current Password"
          value={currentPassword}
          onChange={(val) => {
            setCurrentPassword(val);
            if (activeError) setClientError(null);
          }}
        />
        <div>
          <PasswordField
            label="New Password"
            value={newPassword}
            onChange={(val) => {
              setNewPassword(val);
              if (activeError) setClientError(null);
            }}
          />
          <p className="mt-1 text-[11px] text-[#98A2B3]">
            Must be at least 8 characters and include at least 1 letter and 1 number.
          </p>
        </div>
        <PasswordField
          label="Confirm New Password"
          value={confirmPassword}
          onChange={(val) => {
            setConfirmPassword(val);
            if (activeError) setClientError(null);
          }}
          error={confirmError}
        />
      </div>
    </ConfirmModal>
  );
}
