"use client";
import { useSessionStore, useSessionTokenStore } from "@store/Sesion.Store";
import { ApiError } from "@models/Server.Error.model";
import { ISession } from "@models/Session.model";
import EvangelizeBanner from "@components/EvangelizeBanner/EvangelizeBanner";
import {
    login,
    loginAndVerificate,
    recoveryAccountWithCode,
    sendRecoveryCode,
} from "@services/Session.Login";
import Checkbox from "@mui/material/Checkbox";
import Textbox from "@components/Textbox/Textbox";
import Button from "@components/Button/Button";
import ButtonGoogle from "./LoginGoogle";
import { GoogleOAuthProvider } from "@react-oauth/google";
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import * as Yup from "yup";
import { useAlert } from "@store/Alert.Store";
import Link from "next/link";
import AnimatedContainer from "@components/AnimatedConainer/AnimatedContainer";
import { LOGIN_ACTIONS, useLoginActionStore } from "@core/Store/LoginAction.Store";
import HeaderConfProvider from "../../HeaderConfProvider/HeaderConfProvider";
import { EVENT_TYPES, useEventHandlerStore } from "@core/Store/EventHandler.Store";
import { ScrollToTop } from "@core/app/components/ScrollTop";
import { useNavigation } from "@core/app/hooks/goto";

interface LoginProps {
    verification?: boolean;
    recovery?: boolean;
    recoveryCode?: boolean;
}
export default function Login(props: LoginProps) {
    const { verification = false, recovery = false, recoveryCode = false } = props;
    const router = useRouter();
    const loginAction = useLoginActionStore();
    const SessionInfo = useSessionStore();
    const SessionToken = useSessionTokenStore();
    const alert = useAlert();
    const eventHandler = useEventHandlerStore();

    const [email, setEmail] = useState("");
    const [password, setPassword] = useState("");
    const [verificationCode, setVerificationCode] = useState("");
    const [checkReadTerms, setCheckReadTerms] = useState(false);

    const clientId = process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID || "";

    const { goTo } = useNavigation();

    const createSession = (userSession: ISession, msg: string) => {
        SessionInfo.setUser(userSession);
        SessionToken.setToken(userSession.userToken);
        SessionInfo.setLoginState("success");
        alert.showSuccess(msg);
    };

    const manageLoginActions = () => {
        const toUrl = process.env.NEXT_PUBLIC_DEFAULT_PATH_AFTER_LOGIN || "/";
        if (loginAction.action !== LOGIN_ACTIONS.NONE) {
            goTo(loginAction.url);
            loginAction.clear();
        } else {
            if (SessionInfo.subscription && SessionInfo.subscription.plan) {
                goTo("/landing/dashboard");
                return;
            }

            goTo(toUrl);
        }
    };

    const clearSession = (msg: string) => {
        SessionInfo.clear();
        SessionToken.setToken("");
        alert.showError(msg);
        SessionInfo.setLoginState("error");
    };

    const verificateLogin = () => {
        const schema = Yup.object().shape({
            verificationCode: Yup.string()
                .length(6, "El código de verificacion debe tener 6 digitos")
                .required("El código de verificacion es obligatorio."),
            password: Yup.string()
                .min(8, "La contraseña debe tener al menos 8 caracteres.")
                .required("El campo de contraseña es obligatorio."),
            email: Yup.string()
                .email("Debe ingresar un correo electrónico válido.")
                .required("El campo de correo electrónico es obligatorio."),
        });

        eventHandler.setEventType(EVENT_TYPES.LOADING);
        schema
            .validate({ email, password, verificationCode }, { abortEarly: true, strict: true })
            .then(() => {
                SessionInfo.setLoginState("started");
                loginAndVerificate(email, password, verificationCode)
                    .then((userSession: ISession) => {
                        createSession(
                            userSession,
                            "Registro compleatado. Bienvenido a turnosXpress."
                        );
                    })
                    .catch((error) => {
                        clearSession(error.format());
                    })
                    .finally(() => {
                        eventHandler.setEventType(EVENT_TYPES.SLEEP);
                    });
            })
            .catch((error) => {
                const e = error as Yup.ValidationError;
                clearSession("Ha ocurrido un error. Por favor intentelo nuevamente. " + e.message);
            })
            .finally(() => {
                eventHandler.setEventType(EVENT_TYPES.SLEEP);
            });
    };

    const sendRecoveryMail = () => {
        const schema = Yup.object().shape({
            email: Yup.string()
                .email("Debe ingresar un correo electrónico válido.")
                .required("El campo de correo electrónico es obligatorio."),
        });

        eventHandler.setEventType(EVENT_TYPES.LOADING);
        schema
            .validate({ email }, { abortEarly: true, strict: true })
            .then(() => {
                SessionInfo.setLoginState("started");
                sendRecoveryCode(email)
                    .then(() => {
                        alert.showSuccess(
                            "Se ha enviado un correo de recuperación a la cuenta indicada."
                        );
                        setTimeout(() => {
                            router.push("/landing/recover-account/verify");
                        }, 1000);
                    })
                    .catch((error) => {
                        clearSession(error.format());
                    })
                    .finally(() => {
                        eventHandler.setEventType(EVENT_TYPES.SLEEP);
                    });
            })
            .catch((error) => {
                const e = error as Yup.ValidationError;
                clearSession(e.message);
            })
            .finally(() => {
                eventHandler.setEventType(EVENT_TYPES.SLEEP);
            });
    };

    const recoveryAccount = () => {
        const schema = Yup.object().shape({
            email: Yup.string()
                .email("Debe ingresar un correo electrónico válido.")
                .required("El campo de correo electrónico es obligatorio."),
            verificationCode: Yup.string()
                .length(6, "El código de verificación debe tener 6 digitos")
                .required("El código de verificacion es obligatorio."),
            password: Yup.string()
                .min(8, "La contraseña debe tener al menos 8 caracteres.")
                .required("El campo de contraseña es obligatorio."),
        });

        eventHandler.setEventType(EVENT_TYPES.LOADING);
        schema
            .validate({ email, verificationCode, password }, { abortEarly: true, strict: true })
            .then(() => {
                recoveryAccountWithCode(email, password, verificationCode)
                    .then(() => {
                        alert.showSuccess("Se ha cambiado la contraseña de la cuenta indicada.");
                        setTimeout(() => {
                            goTo("/landing/login");
                        }, 1000);
                    })
                    .catch((error) => {
                        clearSession(error.format());
                    })
                    .finally(() => {
                        eventHandler.setEventType(EVENT_TYPES.SLEEP);
                    });
            })
            .catch((error) => {
                const e = error as Yup.ValidationError;
                clearSession(e.message);
            })
            .finally(() => {
                eventHandler.setEventType(EVENT_TYPES.SLEEP);
            });
    };

    const iniciarSesion = () => {
        const schema = Yup.object().shape({
            email: Yup.string()
                .email("Debe ingresar un correo electrónico válido.")
                .required("El campo de correo electrónico es obligatorio."),
            password: Yup.string()
                .min(8, "La contraseña debe tener al menos 8 caracteres.")
                .required("El campo de contraseña es obligatorio."),
        });

        eventHandler.setEventType(EVENT_TYPES.LOADING);

        schema
            .validate({ email, password }, { abortEarly: false })
            .then(() => {
                SessionInfo.setLoginState("started");
                login(email, password)
                    .then((userSession: ISession) => {
                        createSession(userSession, "Has iniciado sesión correctamente!");
                    })
                    .catch((error: ApiError) => {
                        clearSession(error.format());
                    })
                    .finally(() => {
                        eventHandler.setEventType(EVENT_TYPES.SLEEP);
                    });
            })
            .catch((error) => {
                let errorDesc = "";
                if (error instanceof Yup.ValidationError) {
                    const e: Yup.ValidationError = error as Yup.ValidationError;
                    errorDesc = e.errors.reduce((prev, curr) => prev + " " + curr, "");
                } else {
                    errorDesc = "Ha ocurrido un error. Por favor intentelo nuevamente.";
                }
                clearSession(errorDesc);
            })
            .finally(() => {
                eventHandler.setEventType(EVENT_TYPES.SLEEP);
            });
    };

    useEffect(() => {
        if (SessionInfo.loged) {
            manageLoginActions();
        }
    }, [SessionInfo.loged]);

    return (
        <AnimatedContainer
            color="#aeaeae"
            minSize={150}
            maxSize={500}
            items={10}
            style={{
                minHeight: "100vh",
                display: "flex",
                flexDirection: "column",
                justifyContent: "center",
                alignItems: "center",
                background:
                    "linear-gradient(180deg, var(--wine-darkest) 0%, var(--wine-dark) 100%)",
            }}
        >
            <ScrollToTop />
            <div className="homeCentered">
                <HeaderConfProvider />
                <GoogleOAuthProvider clientId={clientId}>
                    <div
                        style={{
                            paddingLeft: "20px",
                            paddingRight: "20px",
                            translate: "0px -30px",
                        }}
                    >
                        <div className="card">
                            <div
                                style={{
                                    textAlign: "center",
                                    paddingBottom: "30px",
                                    paddingTop: "20px",
                                    position: "relative",
                                }}
                            >
                                {verification && (
                                    <>
                                        <h1 className="homeTitleHeader">Finalizar registro</h1>
                                        <p>
                                            Hemos enviado un correo electronico a tu cuenta con el
                                            código de verificación para completar el registro.{" "}
                                            <strong>Por favor revisa tu bandeja de entrada.</strong>
                                        </p>
                                    </>
                                )}
                                {recovery && (
                                    <>
                                        <h1 className="homeTitleHeader">Reestablecer clave</h1>
                                        <p>
                                            Te enviaremos un correo electrónico a la dirección
                                            registrada con tu cuenta. Asegúrate de proporcionarnos
                                            el mismo correo con el que te registraste.{" "}
                                            <strong>
                                                Revisa tu bandeja de entrada y, si no lo encuentras,
                                                también la carpeta de spam. Luego, sigue las
                                                instrucciones.
                                            </strong>
                                        </p>
                                    </>
                                )}
                                {recoveryCode && (
                                    <>
                                        <h1 className="homeTitleHeader">Recuperar el acceso</h1>
                                        <p>
                                            Hemos enviado un correo electrónico a tu cuenta con el
                                            código de verificación para completar el proceso de
                                            recuperación.{" "}
                                            <strong>
                                                Ingresa tu email, la nueva clave y el código de
                                                verificación que te enviamos.
                                            </strong>
                                        </p>
                                    </>
                                )}
                                {!verification && !recovery && !recoveryCode && (
                                    <h1 className="homeTitleHeader">Ingresar</h1>
                                )}
                                <Textbox
                                    name="name"
                                    placeholder="Email"
                                    type="text"
                                    value={email}
                                    width="100%"
                                    onChange={(e) => {
                                        setEmail(e.target.value);
                                    }}
                                    onKeyUp={(e) => {
                                        if (!verification && !recovery && !recoveryCode) {
                                            if (e.key === "Enter") {
                                                document.getElementById("password")?.focus();
                                            }
                                        }
                                    }}
                                />
                                {!recovery && (
                                    <Textbox
                                        name="password"
                                        placeholder="Clave"
                                        type="password"
                                        value={password}
                                        width="100%"
                                        onChange={(e) => {
                                            setPassword(e.target.value);
                                        }}
                                        onKeyUp={(e) => {
                                            if (!verification && !recovery && !recoveryCode) {
                                                if (e.key === "Enter") {
                                                    iniciarSesion();
                                                }
                                            }
                                        }}
                                    />
                                )}

                                {(verification || recoveryCode) && (
                                    <Textbox
                                        placeholder="Código de verificaion"
                                        type="text"
                                        value={verificationCode}
                                        width="100%"
                                        onChange={(e) => {
                                            setVerificationCode(e.target.value);
                                        }}
                                    />
                                )}

                                {verification && (
                                    <Button
                                        name="btnLogin"
                                        text="Verificar"
                                        width="100%"
                                        onClick={verificateLogin}
                                        style={{ marginTop: "20px" }}
                                        type="submit"
                                    />
                                )}

                                {recovery && (
                                    <Button
                                        name="btnLogin"
                                        text="Enviar email"
                                        width="100%"
                                        onClick={sendRecoveryMail}
                                        style={{ marginTop: "20px" }}
                                        type="submit"
                                    />
                                )}

                                {recoveryCode && (
                                    <Button
                                        name="btnLogin"
                                        text="Cambiar clave"
                                        width="100%"
                                        onClick={recoveryAccount}
                                        style={{ marginTop: "20px" }}
                                        type="submit"
                                    />
                                )}

                                {!verification && !recovery && !recoveryCode && (
                                    <Button
                                        name="btnLogin"
                                        text="Ingresar"
                                        width="100%"
                                        onClick={iniciarSesion}
                                        style={{ marginTop: "20px" }}
                                        type="submit"
                                    />
                                )}

                                {!verification && !recovery && !recoveryCode && (
                                    <div>
                                        <div
                                            style={{
                                                display: "flex",
                                                flexDirection: "row",
                                                alignItems: "flex-start",
                                                justifyContent: "flex-start",
                                            }}
                                        >
                                            <Checkbox
                                                checked={checkReadTerms}
                                                onClick={() => setCheckReadTerms(!checkReadTerms)}
                                            />
                                            <div style={{ marginTop: "8px" }}>
                                                Declaro que acepto los siguientes&nbsp;
                                                <Link href="/landing/terms">
                                                    Términos y condiciones
                                                </Link>{" "}
                                                y{" "}
                                                <Link href="/landing/privacy">
                                                    Políticas de privacidad
                                                </Link>
                                            </div>
                                        </div>
                                        <ButtonGoogle termsReaded={checkReadTerms} />
                                    </div>
                                )}
                                {!recoveryCode && (
                                    <p style={{ marginTop: "20px" }}>
                                        No tienes una cuenta?&nbsp;
                                        <Link href="/landing/signup">Registrate!</Link>
                                    </p>
                                )}

                                {!recovery && !recoveryCode && (
                                    <Link
                                        href="/landing/recover-account"
                                        style={{ display: "block", marginTop: "10px" }}
                                    >
                                        Olvide mi clave!
                                    </Link>
                                )}
                                {recovery && !recoveryCode && (
                                    <Link
                                        href="/landing/recover-account/verify"
                                        style={{ display: "block", marginTop: "10px" }}
                                    >
                                        Ya tengo el código de verificación!
                                    </Link>
                                )}
                            </div>
                        </div>
                    </div>
                </GoogleOAuthProvider>
            </div>
            <EvangelizeBanner variant="popup" delay={4000} />
        </AnimatedContainer>
    );
}
