/* eslint-disable import/extensions */
import { XMarkIcon } from '@heroicons/react/20/solid';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { toast } from 'sonner';

import { PasswordStrengthCard } from '@/components/card/PasswordStrengthCard';
import { PasswordInput } from '@/components/input/PasswordInput';
import { ArrowPathIcon } from '@heroicons/react/24/outline';
import clsx from 'clsx';

type EncryptionModalProps = {
  isOpen: boolean;
  onCancel: () => void;
  handleSubmitEncrypt: (password: string) => void;
  auditName: string;
  isGeneratingPDF: boolean;
};

export const EncryptionModal: React.FC<EncryptionModalProps> = ({
  auditName,
  isOpen,
  isGeneratingPDF,
  onCancel,
  handleSubmitEncrypt,
}) => {
  const { t } = useTranslation();
  const [password, setPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');

  useEffect(() => {
    if (isOpen) {
      document.body.style.overflow = 'hidden';
    } else {
      document.body.style.overflow = 'unset';
    }
  }, [isOpen]);

  const generatePassword = () => {
    const charset =
      // eslint-disable-next-line no-secrets/no-secrets
      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()';
    const passwordLength = 32;
    let newPassword = '';

    const randomValues = new Uint32Array(passwordLength);
    window.crypto.getRandomValues(randomValues);

    for (let i = 0; i < passwordLength; i++) {
      if (randomValues[i] % 7 === 0) {
        newPassword += '!@#$%^&*()'.charAt(randomValues[i] % 10);
      } else if (randomValues[i] % 3 === 0) {
        newPassword += '0123456789'.charAt(randomValues[i] % 10);
      } else {
        newPassword += charset.charAt(randomValues[i] % charset.length);
      }
    }

    return newPassword;
  };

  const handlePasswordGen = () => {
    const generated = generatePassword();
    setPassword(generated);
    setConfirmPassword(generated);
    void navigator.clipboard.writeText(generated);
    toast.info(t('msg.copiedToClipboard'));
  };

  useEffect(() => {
    setPassword('');
    setConfirmPassword('');
  }, [onCancel]);

  return (
    isOpen && (
      <div className="fixed z-50 inset-0 flex items-center justify-center bg-stone-900 bg-opacity-50">
        <div className="bg-gray-900 rounded-lg shadow-lg p-6 w-full max-w-lg">
          <div className="ml-3 mt-3 flex justify-between items-center mb-2">
            <h2 className="text-xl font-bold text-center text-gray-200">
              {`${t('encryption')} (${auditName})`}
            </h2>
            <button
              className="bg-transparent text-white p-2 rounded mx-3"
              onClick={onCancel}
              type="button"
            >
              <XMarkIcon className="h-6 w-6" />
            </button>
          </div>
          <hr className="h-1 mb-3 bg-gray-600 border-0 rounded" />

          <div className="mb-2 text-gray-200 py-4">
            <div className="flex flex-col">
              <PasswordInput
                disabled={isGeneratingPDF}
                id="password"
                label={t('password')}
                name="password"
                onChange={setPassword}
                placeholder={t('password')}
                value={password}
              />
              <div className="py-2 pr-9">
                <PasswordStrengthCard password={password} />
              </div>
              <PasswordInput
                disabled={isGeneratingPDF}
                id="confirmPassword"
                label={t('confirmPassword')}
                name="confirmPassword"
                onChange={setConfirmPassword}
                placeholder={t('confirmPassword')}
                value={confirmPassword}
              />
            </div>
            <div
              className={
                password === confirmPassword || confirmPassword === ''
                  ? 'flex items-center justify-center text-red-500/75 pt-2 invisible'
                  : 'flex items-center justify-center text-red-500/75 pt-2'
              }
            >
              <p aria-live="polite">{t('err.passwordsDontMatch')}</p>
            </div>
          </div>
          <hr className="h-1 mb-3 bg-gray-600 border-0 rounded" />

          <div className="flex justify-end">
            <button
              className="bg-gray-500 text-white px-4 py-2 rounded mr-2"
              onClick={onCancel}
              type="button"
            >
              {t('btn.cancel')}
            </button>
            <button
              className={clsx('text-white px-4 py-2 rounded mr-2', {
                'bg-green-500': !isGeneratingPDF,
                'bg-green-500/70': isGeneratingPDF,
              })}
              disabled={isGeneratingPDF}
              onClick={handlePasswordGen}
              type="button"
            >
              {t('btn.generatePassword')}
            </button>
            {!isGeneratingPDF ? (
              <button
                className={
                  !(password === confirmPassword) ||
                  password.length < 1 ||
                  confirmPassword.length < 1
                    ? 'bg-blue-500/50 text-white/50 px-4 py-2 rounded'
                    : 'bg-blue-500 text-white px-4 py-2 rounded'
                }
                disabled={
                  !(password === confirmPassword) ||
                  password.length < 1 ||
                  confirmPassword.length < 1
                }
                onClick={() => handleSubmitEncrypt(password)}
                type="button"
              >
                {t('btn.submitEncryption')}
              </button>
            ) : (
              <ArrowPathIcon className="h-8 w-8 animate-spin text-blue-500" />
            )}
          </div>
        </div>
      </div>
    )
  );
};
