'use client';

import React, { useState, type FormEvent, type ChangeEvent, useEffect } from 'react'
import { useAuthStore } from '@/zustand/authStore';
import { redirect } from 'next/navigation';
import StepEnterPassword from '@/features/auth/components/StepEnterPassword';
import StepEnterNumber from '@/features/auth/components/StepEnterNumber';
import StepEnterOtp from '@/features/auth/components/StepEnterOtp';
import { AUTH_PAGE_ELEMENT, AUTH_STEP } from '@/enums';
import { useCountdown } from '@/hooks/useCountdown';
import StepNewPassword from '@/features/auth/components/StepNewPassword';
import AuthFormWrapper from '@/features/auth/components/AuthFormWrapper';
import { useLogin } from '@/hooks/auth/useLogin';
import { useSignup } from '@/hooks/auth/useSignup';
import { useCheckUserExistsLazy } from '@/hooks/auth/useCheckUserExists';
import { useOtpRequest } from '@/hooks/auth/useOtpRequest';
import { useOtpValidation } from '@/hooks/auth/useOtpValidation';
import { useResetPassword } from '@/hooks/auth/useResetPassword';

type Props = object

function AuthIndex({ }: Props) {
    const [isPending, setIsPending] = useState(false);
    const [number, setNumber] = useState("");
    const [password, setPassword] = useState("");
    const [passwordRepeat, setPasswordRepeat] = useState("");
    const [otp, setOtp] = useState("");
    const [showPassword, setShowPassword] = useState(false);
    const [showPasswordRepeat, setShowPasswordRepeat] = useState(false);
    const [rememberMe, setRememberMe] = useState(false);
    const [step, setStep] = useState(AUTH_STEP.ENTER_NUMBER);
    const { timerRunning, secondsLeft, restart, stop } = useCountdown(step === AUTH_STEP.ENTER_OTP);

    const isAuthenticated = useAuthStore((state) => state.isAuthenticated)
    const loginMutation = useLogin()
    const signupMutation = useSignup()
    const { run: runUserExistCheck } = useCheckUserExistsLazy()
    const { run: runOtpRequest } = useOtpRequest();
    const { run: runOtpValidation } = useOtpValidation();
    const { run: runResetPassword } = useResetPassword();

    const resetStates = () => {
        setNumber('');
        setPassword('');
        setPasswordRepeat('');
        setOtp('');
        setShowPassword(false);
        setShowPasswordRepeat(false);
        setRememberMe(false);
        stop();
    }

    useEffect(() => {
        if (isAuthenticated) {
            redirect("/");
        }
    }, [isAuthenticated])

    useEffect(() => {
        if (step === AUTH_STEP.ENTER_OTP) {
            setOtp('');
            console.log("REQUEST OTP")
            runOtpRequest(number);
        }
    }, [step]);

    const onChange = (e: ChangeEvent<HTMLInputElement>) => {
        if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PHONE) {
            setNumber(() => e.target.value)
        }
        else if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PASSWORD) {
            setPassword(() => e.target.value)
        }
        else if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_PASSWORD_REPEAT) {
            setPasswordRepeat(() => e.target.value)
        }
        else if (e.target.name == AUTH_PAGE_ELEMENT.INPUT_REMEMBER_ME) {
            setRememberMe((state) => !state)
        }
        else if (e.target.name.startsWith(AUTH_PAGE_ELEMENT.INPUT_OTP)) {
            const index = +e.target.name.split('-')[2];
            const prev = otp.padEnd(6).split('');
            prev[index] = e.target.value;
            const next = prev.join('');
            if (otp.length >= 6 && next.trim().length >= otp.length) return;
            setOtp(next.trimEnd());
        }
    }

    const onClick = async (e: React.MouseEvent<HTMLButtonElement, MouseEvent> | React.MouseEvent<HTMLInputElement, MouseEvent>) => {
        e.stopPropagation();
        const target = e.target as HTMLButtonElement;

        if (target.id === AUTH_PAGE_ELEMENT.TOGGLE_PASSWORD) {
            setShowPassword((state) => !state);
        }
        if (target.id === AUTH_PAGE_ELEMENT.TOGGLE_REPEAT_PASSWORD) {
            setShowPasswordRepeat((state) => !state);
        }
        else if (target.id === AUTH_PAGE_ELEMENT.RESET_PASSWORD) {
            setShowPassword(false);
            setShowPasswordRepeat(false);
            setPassword('');
            setPasswordRepeat('');
            setStep(() => AUTH_STEP.ENTER_OTP)
        }
        else if (target.id === AUTH_PAGE_ELEMENT.RESEND_OTP) {
            if (!timerRunning) {
                try {
                    await runOtpRequest(number);
                    restart();
                } catch {
                    console.error("Could not ask for otp")
                }
            }
        }
    };

    const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        try {
            setIsPending(true);
            if (step == AUTH_STEP.ENTER_NUMBER) {

                if (await runUserExistCheck(number)) {
                    setStep(AUTH_STEP.ENTER_PASSWORD)
                } else {
                    setStep(AUTH_STEP.ENTER_OTP);
                }
            }
            else if (step == AUTH_STEP.ENTER_PASSWORD) {
                try {
                    await loginMutation.mutateAsync({ phone: number, password })
                    console.log("Logged in")
                    redirect("/")
                }
                catch (e) {
                    console.error("Wrong credentials: ", e)
                }
            }
            else if (step == AUTH_STEP.ENTER_OTP) {
                if (!await runOtpValidation({ phone: number, otp })) {
                    setOtp('');
                    console.error('Wrong otp');
                }
                stop();
                console.log(await runUserExistCheck(number));
                if (await runUserExistCheck(number)) {
                    console.log("1")
                    setStep(AUTH_STEP.ENTER_RESET_PASSWORD)
                } else {
                    console.log("2")
                    setStep(AUTH_STEP.ENTER_NEW_PASSWORD)
                }
            }
            else if (step == AUTH_STEP.ENTER_RESET_PASSWORD) {
                console.log("Password changed")
                try {
                    await runResetPassword({
                        phone: number,
                        newPassword: password,
                        otp
                    })
                    resetStates();
                    setStep(AUTH_STEP.ENTER_NUMBER)
                } catch (ex) {
                    console.error('Password reset failed: ', ex)
                }
            }
            else if (step == AUTH_STEP.ENTER_NEW_PASSWORD) {
                try {
                    await signupMutation.mutateAsync({ phone: number, password })
                    console.log("Signed up")
                    redirect("/")
                }
                catch (e) {
                    console.error("Could not signup: ", e)
                }
            }
        } catch (ex) {
            console.error(ex)
        } finally {
            setIsPending(false);
        }
    }

    const stepMap = {
        [AUTH_STEP.ENTER_NUMBER]: <StepEnterNumber disabled={isPending} onChange={onChange} value={number} />,
        [AUTH_STEP.ENTER_PASSWORD]: <StepEnterPassword disabled={isPending} onChange={onChange} onClick={onClick} value={password} passwordVisible={showPassword} rememberMe={rememberMe} />,
        [AUTH_STEP.ENTER_OTP]: <StepEnterOtp disabled={isPending} onChange={onChange} onClick={onClick} phoneNumber={number} value={otp} timerRunning={timerRunning} secondsLeft={secondsLeft} />,
        [AUTH_STEP.ENTER_NEW_PASSWORD]: <StepNewPassword disabled={isPending} onChange={onChange} onClick={onClick} value={password} repeatValue={passwordRepeat} passwordVisible={showPassword} repeatPasswordVisible={showPasswordRepeat} />,
        [AUTH_STEP.ENTER_RESET_PASSWORD]: <StepNewPassword isReset disabled={isPending} onChange={onChange} onClick={onClick} value={password} repeatValue={passwordRepeat} passwordVisible={showPassword} repeatPasswordVisible={showPasswordRepeat} />,
    }

    return (
        <AuthFormWrapper isPending={isPending} onSubmit={onSubmit}>
            {stepMap[step] || 'say what now?'}
        </AuthFormWrapper>
    )
}

export default AuthIndex
