import { useState, useContext, useEffect, useCallback, MouseEvent } from 'react';
import { AccountUserProfileContext } from '../hooks';
import { toast } from 'sonner';
import { useAuthContext } from '@/auth';
import { KeenIcon } from '@/components';
import clsx from 'clsx';

type PasswordType = 'password' | 'retype_password' | 'current_password';
const Password = () => {
  const { setPassword } = useContext(AccountUserProfileContext);
  const { getUser } = useAuthContext();

  const [newPassword, setNewPassword] = useState('');
  const [currentPassword, setCurrentPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [messagePassword, setMessagePassword] = useState(true);
  const [showPassword, setShowPassword] = useState({
    current_password: false,
    password: false,
    retype_password: false
  });

  const [passwordErrors, setPasswordErrors] = useState<string[]>([]);

  const validatePassword = (password: string) => {
    const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(password);
    const hasCapitalLetter = /[A-Z]/.test(password);
    const hasNumber = /[0-9]/.test(password);
    return hasSpecialChar && hasCapitalLetter && hasNumber;
  };

  useEffect(() => {
    const passwordsMatch = newPassword === confirmPassword;
    const isPasswordValid = validatePassword(newPassword);
    setMessagePassword(passwordsMatch && isPasswordValid);

    const errors: string[] = [];
    if (newPassword) {
      if (!/[A-Z]/.test(newPassword)) {
        errors.push('Password must contain at least one capital letter');
      }
      if (!/[0-9]/.test(newPassword)) {
        errors.push('Password must contain at least one number');
      }
      if (!/[!@#$%^&*(),.?":{}|<>]/.test(newPassword)) {
        errors.push('Password must contain at least one special character');
      }
      if (newPassword !== confirmPassword) {
        errors.push('Passwords do not match');
      }
    }
    setPasswordErrors(errors);
  }, [newPassword, confirmPassword]);

  const handleResetPassword = useCallback(async () => {
    const user: any = await getUser();

    if (!messagePassword) {
      toast.error('Passwords do not match!');
      return;
    }

    setIsSubmitting(true);

    try {
      await setPassword({
        current_password: currentPassword,
        password: newPassword,
        retype_password: confirmPassword,
        username: user.data.username ?? ''
      });

      setNewPassword('');
      setConfirmPassword('');
      setCurrentPassword('');
    } catch (error: any) {
      const errorMessage =
        error?.response?.data?.message ||
        error?.message ||
        'An error occurred while resetting the password.';
      toast.error(errorMessage);
    } finally {
      setIsSubmitting(false);
    }
  }, [currentPassword, newPassword, newPassword, messagePassword, getUser]);

  const isButtonDisabled = isSubmitting || !newPassword || !confirmPassword || !messagePassword;

  const togglePassword = useCallback((event: MouseEvent<HTMLButtonElement>, key: string) => {
    event.preventDefault();
    setShowPassword((prev) => ({ ...prev, [key]: !prev[key as PasswordType] }));
  }, []);

  return (
    <div className="card pb-2.5">
      <div className="card-header" id="password_settings">
        <h3 className="card-title">Password</h3>
      </div>
      <div className="card-body grid gap-5">
        <div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
          <label className="form-label max-w-56">Current Password</label>
          <div className="input">
            <input
              type={showPassword.current_password ? 'text' : 'password'}
              className="form-control"
              placeholder="Current password"
              value={currentPassword}
              onChange={(e) => setCurrentPassword(e.target.value)}
              disabled={isSubmitting}
            />
            <button className="btn btn-icon" onClick={(e) => togglePassword(e, 'current_password')}>
              <KeenIcon
                icon="eye"
                className={clsx('text-gray-500', { hidden: showPassword.current_password })}
              />
              <KeenIcon
                icon="eye-slash"
                className={clsx('text-gray-500', { hidden: !showPassword.current_password })}
              />
            </button>
          </div>
        </div>
        <div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
          <label className="form-label max-w-56">New Password</label>
          <div className="input">
            <input
              className="form-control"
              placeholder="New password"
              value={newPassword}
              onChange={(e) => setNewPassword(e.target.value)}
              disabled={isSubmitting}
              type={showPassword.password ? 'text' : 'password'}
            />
            <button className="btn btn-icon" onClick={(e) => togglePassword(e, 'password')}>
              <KeenIcon
                icon="eye"
                className={clsx('text-gray-500', { hidden: showPassword.password })}
              />
              <KeenIcon
                icon="eye-slash"
                className={clsx('text-gray-500', { hidden: !showPassword.password })}
              />
            </button>
          </div>
        </div>
        <div className="mb-2.5">
          <div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
            <label className="form-label max-w-56">Confirm New Password</label>
            <div className="input">
              <input
                type={showPassword.retype_password ? 'text' : 'password'}
                className="form-control"
                placeholder="Confirm new password"
                value={confirmPassword}
                onChange={(e) => setConfirmPassword(e.target.value)}
                disabled={isSubmitting}
              />
              <button
                className="btn btn-icon"
                onClick={(e) => togglePassword(e, 'retype_password')}
              >
                <KeenIcon
                  icon="eye"
                  className={clsx('text-gray-500', { hidden: showPassword.retype_password })}
                />
                <KeenIcon
                  icon="eye-slash"
                  className={clsx('text-gray-500', { hidden: !showPassword.retype_password })}
                />
              </button>
            </div>
          </div>
          <div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
            <label className="form-label max-w-56 text-white">Confirm New Password</label>
            {passwordErrors.length > 0 && (
              <div className="text-xs text-red-500 mt-1 ms-3">
                {passwordErrors.map((error, index) => (
                  <p key={index}>{error}</p>
                ))}
              </div>
            )}
          </div>
        </div>

        <div className="flex justify-end">
          <button
            className="btn btn-primary"
            onClick={handleResetPassword}
            disabled={isButtonDisabled}
          >
            {isSubmitting ? 'Updating...' : 'Update Password'}
          </button>
        </div>
      </div>
    </div>
  );
};

export { Password };
