import React, { useMemo, useState, useEffect } from 'react';
import { useAppContext } from './app';
import { flash } from './toast';
import { Link } from 'react-router-dom';
import Logo from './logo';

const ResetPassword: React.FC<{}> = () => {
    const [email, setEmail] = useState('');
    const [code, setCode] = useState('');
    const [newPassword, setNewPassword] = useState('');
    const [confirmPassword, setConfirmPassword] = useState('');
    const [submitting, setSubmitting] = useState(false);
    const [step, setStep] = useState(1);
    const [showPassword, setShowPassword] = useState(false);
    const [showConfirmPassword, setShowConfirmPassword] = useState(false);
    const { request, setState, redirect, queries } = useAppContext() as any;
    const token: string = useMemo(() => queries['token'] || '', [queries]);
    const emailAddress: string = useMemo(() => queries['email'] || '', [queries]);

    const handleTogglePassword = () => setShowPassword(!showPassword);
    const handleToggleConfirmPassword = () => setShowConfirmPassword(!showConfirmPassword);

    const handleSubmitEmail = (event: React.FormEvent) => {
        event.preventDefault();
        if (!email.trim()) {
            flash('Please enter an email address');
            return;
        }

        setSubmitting(true);
        request('/reset-password', 'POST', { email })
            .then(() => {
                flash('Password reset link sent to your email');
                setStep(2);
            })
            .catch((error: any) => {
                flash('An error occurred');
                console.error(error);
            })
            .finally(() => {
                setSubmitting(false);
            });
    };

    const handleVerifyCode = async (event?: React.FormEvent) => {
        event?.preventDefault();
        if (!code.trim() && !token) {
            flash('Please enter the verification code');
            return;
        }

        setSubmitting(true);
        try {
            const result = await request('/verify-code', 'POST', { email: emailAddress || email, code: token || code });
            flash('Code verified successfully');
            setCode(result.token);
            setStep(3);
        } catch (error: any) {
            flash('Invalid or expired code');
            console.error(error);
            throw error;
        } finally {
            setSubmitting(false);
        }
    };

    const handleResetPassword = (event: React.FormEvent) => {
        event.preventDefault();
        if (!newPassword || !confirmPassword) {
            flash('Please fill in all fields');
            return;
        }
        if (newPassword !== confirmPassword) {
            flash('Passwords do not match');
            return;
        }
        if (!/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{12,}$/.test(newPassword)) {
            flash('Password must be at least 12 characters long and include uppercase, lowercase, number, and symbol');
            return;
        }

        setSubmitting(true);
        request('/finalize-password', 'POST', { email: emailAddress || email, token: code, password: newPassword })
            .then(({ token, key, iv }: { token: string; key: string; iv: string }) => {
                flash('Password has been reset successfully');
                if (!token || !key || !iv) {
                    return redirect('/login');
                }
                localStorage.setItem('token', JSON.stringify({ token, key, iv }));
                setState({ token, key, iv });
                redirect('/');
            })
            .catch((error: any) => {
                flash('An error occurred');
                console.error(error);
            })
            .finally(() => {
                setSubmitting(false);
            });
    };

    useEffect(() => {
        if (token) {
            handleVerifyCode().catch(() => {
                flash('Invalid or expired code');
                redirect('/reset-password');
            });
        }
    }, [token]);

    return (
        <div className="w-full flex flex-col gap-2 items-center justify-center h-full">
            <Logo />
            <h1>Reset Password</h1>
            {submitting ? (
                <div><h3>Submitting...</h3></div>
            ) : step === 1 ? (
                <>
                    <form className="reset-password-form" onSubmit={handleSubmitEmail}>
                        <div>
                            <label htmlFor="email">Email:</label>
                            <input
                                value={email}
                                onChange={(e) => setEmail(e.target.value)}
                                type="email"
                                id="email"
                                name="email"
                                required
                            />
                        </div>
                        <button type="submit">Send Reset Link</button>
                    </form>
                    <div>
                        <Link to="/login">
                            <span>Back to Login</span>
                        </Link>
                    </div>
                </>
            ) : step === 2 ? (
                <>
                    <form className="verify-code-form" onSubmit={handleVerifyCode}>
                        <div>
                            <label htmlFor="code">Verification Code:</label>
                            <input
                                value={code}
                                onChange={(e) => setCode(e.target.value)}
                                type="text"
                                id="code"
                                name="code"
                                required
                            />
                        </div>
                        <button type="submit">Verify Code</button>
                    </form>
                </>
            ) : (
                <>
                    <form className="reset-password-form" onSubmit={handleResetPassword}>
                        <div className="relative">
                            <label htmlFor="newPassword">New Password:</label>
                            <input
                                value={newPassword}
                                onChange={(e) => setNewPassword(e.target.value)}
                                type={showPassword ? "text" : "password"}
                                id="newPassword"
                                name="newPassword"
                                required
                            />
                            <button type="button" onClick={handleTogglePassword} className="absolute inset-y-0 right-0 pr-3 flex items-center">
                                {showPassword ? "Hide" : "Show"}
                            </button>
                        </div>
                        <div className="relative">
                            <label htmlFor="confirmPassword">Confirm Password:</label>
                            <input
                                value={confirmPassword}
                                onChange={(e) => setConfirmPassword(e.target.value)}
                                type={showConfirmPassword ? "text" : "password"}
                                id="confirmPassword"
                                name="confirmPassword"
                                required
                            />
                            <button type="button" onClick={handleToggleConfirmPassword} className="absolute inset-y-0 right-0 pr-3 flex items-center">
                                {showConfirmPassword ? "Hide" : "Show"}
                            </button>
                        </div>
                        <button type="submit">Reset Password</button>
                    </form>
                </>
            )}
        </div>
    );
}

export default ResetPassword;
