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

const SignUp: React.FC<{}> = () => {
    const [submitting, setSubmitting] = useState(false);
    const { request, setState, redirect } = useAppContext() as any;
    const [username, setUsername] = useState('');
    const [password, setPassword] = useState('');
    const [password2, setPassword2] = useState('');
    const [email, setEmail] = useState('');
    const [showPassword, setShowPassword] = useState(false);
    const [showConfirmPassword, setShowConfirmPassword] = useState(false);

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

    const handleSubmit = async (event: React.FormEvent) => {
        event.preventDefault();
        // Perform validation
        if (username.trim() === '') {
            flash('Please enter a username');
            return;
        }
        if (password.trim() === '') {
            flash('Please enter a password');
            return;
        }
        if (password2.trim() === '') {
            flash('Please confirm your password');
            return;
        }
        if (password !== password2) {
            flash('Passwords do not match');
            return;
        }
        if (email.trim() === '') {
            flash('Please enter an email');
            return;
        }
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        if (!emailRegex.test(email)) {
            flash('Please enter a valid email');
            return;
        }
        const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{12,}$/;
        if (!passwordRegex.test(password)) {
            let errorMessage = 'Password must meet the following requirements:\n';

            if (password.length < 12) {
                errorMessage += '- Be 12 characters long\n';
            }

            if (!/(?=.*[a-z])/.test(password)) {
                errorMessage += '- Contain at least one lowercase letter\n';
            }

            if (!/(?=.*[A-Z])/.test(password)) {
                errorMessage += '- Contain at least one uppercase letter\n';
            }

            if (!/(?=.*\d)/.test(password)) {
                errorMessage += '- Contain at least one number\n';
            }

            if (!/(?=.*[@$!%*?&])/.test(password)) {
                errorMessage += '- Contain at least one symbol\n';
            }

            flash(errorMessage);
            return;
        }
        setSubmitting(true);
        request('/register', 'POST', {
            email: email.trim(),
            username: username.trim(),
            password: password.trim()
        }).then((result: { token: string, key: string, iv: string }) => {
            localStorage.setItem('token', JSON.stringify({ token: result.token, key: result.key, iv: result.iv }));
            setState({ token: result.token, key: result.key, iv: result.iv });
            redirect('/');
        }).catch((e: any) => {
            console.error(e);
            flash('An error occurred. Please try again later');
        }).finally(() => {
            setSubmitting(false);
        });
    };

    return (
        <div className="w-full flex flex-col gap-2 items-center justify-center h-full">
            <Logo />
            <h1>Sign Up</h1>
            {submitting ? (
                <div><h3>Submitting...</h3></div>
            ) : (
                <>
                    <form className="login-form" onSubmit={handleSubmit}>
                        <div>
                            <label htmlFor="email">Email:</label>
                            <input 
                                value={email} 
                                onChange={e => setEmail(e.target.value)} 
                                type="text" 
                                id="email" 
                                name="email" 
                            />
                        </div>
                        <div>
                            <label htmlFor="username">Username:</label>
                            <input 
                                value={username} 
                                onChange={e => setUsername(e.target.value)} 
                                type="text" 
                                id="username" 
                                name="username" 
                            />
                        </div>
                        <div className="relative">
                            <label htmlFor="password">Password:</label>
                            <input 
                                value={password} 
                                onChange={e => setPassword(e.target.value)} 
                                type={showPassword ? "text" : "password"} 
                                id="password" 
                                name="password" 
                            />
                            <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="password2">Confirm Password:</label>
                            <input 
                                value={password2} 
                                onChange={e => setPassword2(e.target.value)} 
                                type={showConfirmPassword ? "text" : "password"} 
                                id="password2" 
                                name="password2" 
                            />
                            <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">Submit</button>
                    </form>
                    <Link to="/login">
                        <span>
                            Already have an account? Sign In!
                        </span>
                    </Link>
                </>
            )}
        </div>
    );
}
export default SignUp;