import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form'
import { Form, ContainerLink, Link, ContainerSocial, FacebookLogin, Termos } from './styles'
import { Button, Input, Typography, CircularProgress, Divider as DividerSfe, Icon } from '@sofaltaeu/sofaltaeu-components'
import { CredentialResponse, GoogleLogin } from '@react-oauth/google';
import { LoginStatus, LoginButton, useFacebook  } from 'react-facebook';

import { useMutation } from 'react-query';
import { createToken, createTokenSocial, validarDadosUsuario } from '../../services';
import { useState } from 'react';
import { useSwitchFormContext, FormEnum } from '../../context/switchForm';
import { useSocialTokenContext, Social } from '../../context/socialToken';
import { CreateTokenSocialProps } from '../../interfaces/services/ICreateTokenSocial';
import { FacebookResponse } from '../../interfaces/services/IFacebookResponse';
import { NewCreateAccountProps } from '../../utils/createAccount';

const emailPattern = /^[a-zA-Z0-9._-]+$/;
const schema = z.object({
    email: z
    .string()
    .min(3, "Deve conter pelo menos 3 caracteres")
    .max(100, "Deve conter no máximo 100 caracteres")
    .refine((usuario: string) => emailPattern.test(usuario), {
        message:
            "Somente letras (a-z), numeros(0-9) e pontos(.) são permitidos",
    }),
    password: z.string().min(8, 'A senha deve conter pelo menos 8 caracter(es)'),
})
type FormData = z.infer<typeof schema>

interface FormProps {
    dominioSFE: string,
    empreendimento:string,
    plataforma:string,
    latitude: number,
    longitude: number,
    onSuccess: (token:string) => void,
    isRegister: boolean,
    preConta?: NewCreateAccountProps
}

interface createTokenMutationProps {
    usuario:string,
    senha:string
}


export const FormLogin = ({dominioSFE, empreendimento, plataforma, latitude, longitude, onSuccess, isRegister, preConta}:FormProps) => {
    const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
        resolver: zodResolver(schema),
        mode: 'onBlur',
        defaultValues:{
            email: preConta ? preConta?.usuario : '',
            password:''
        }
    })
    const [error, setError] = useState('')
    const { handleFormSwitch } = useSwitchFormContext()
    const { setToken } = useSocialTokenContext()
    const { init } = useFacebook();


    const mutationLogin = useMutation(({usuario, senha}:createTokenMutationProps)=>createToken({
        apiUrl:dominioSFE,
        usuario,
        senha,
        empreendimento,
        plataforma,
        latitude,
        longitude
    }),
    {
        onSuccess:(data)=>{
            onSuccess(data.token)
        },
        onError: ({response}) => {
            setError(response.data.message);
            setTimeout(()=>setError(''), 3000)
        },
    })
    const mutationSocialLogin = useMutation(
        (body:CreateTokenSocialProps['body'])=>createTokenSocial({apiUrl:dominioSFE, empreendimento, plataforma, body}),
        {
            onSuccess:(data)=>{
                onSuccess(data.token)
            },
            onError: ({response}) => {
                setError(response.data.message);
                setTimeout(()=>setError(''), 3000)
            },
        }
    )

    const validatorDadosUsuarioMutation = useMutation(({email}: { email?: string }) => validarDadosUsuario({ apiUrl: dominioSFE, email }), { onError: ({response}) => response });

    function onSuccessLoginGoogle(credentialResponse: CredentialResponse){
        const token = credentialResponse.credential;
        const audience = credentialResponse.clientId;
        if(token){
            const payload = JSON.parse(window.atob(token.split('.')[1]));

            validatorDadosUsuarioMutation.mutate({email:payload.email}, {
                onError: ({response}) => {
                    if(response.status === 409){

                        const body = {
                            google:{
                                token,
                                audience
                            }
                        }
                        mutationSocialLogin.mutate(body)
                    }

                    if(response.status === 404 && !preConta){
                        setToken<Social.Google>(token, Social.Google)
                        handleFormSwitch(FormEnum.register);
                    }
                }
            })
        }

    }

    const onSuccessLoginFacebook:LoginButton['onSuccess'] = async (response) => {
        if(response.status === LoginStatus.CONNECTED){
            const token = response.authResponse.accessToken;

            const api = await init();

            const FB = await api?.getFB(); // Get original FB object
            FB.api(`me?fields=email,first_name,last_name,picture{url},gender,name,short_name,birthday,location`, (payloadFacebook:FacebookResponse)=> {
                validatorDadosUsuarioMutation.mutate({email:payloadFacebook.email}, {
                    onError: ({response}) => {
                        if(response.status === 409){

                            const body = {
                                facebook:{
                                    accessToken: token
                                 }
                            }
                            mutationSocialLogin.mutate(body)
                        }

                        if(response.status === 404){
                            setToken<Social.Facebook>(payloadFacebook, Social.Facebook)
                            handleFormSwitch(FormEnum.register);
                        }
                    }
                })
            });
        }
    }


    async function onSubmit(data: FormData){
        await mutationLogin.mutateAsync({usuario:data.email, senha:data.password})
    }


    return (
        <>
            <Form onSubmit={handleSubmit(onSubmit)}>
                <Input
                    label='E-mail, Usuario ou CPF'
                    variant={errors.email ? 'error' : 'standard'}
                    helperText={errors.email?.message}
                    disabled={Boolean(preConta)}
                    required
                    {...register('email')}

                />
                <Input
                    label='Senha'
                    variant={errors.password ? 'error' : 'standard'}
                    type='password'
                    required
                    helperText={errors.password?.message}
                    {...register('password')}
                />
                {error &&
                    <Typography variant='body2' color='error'>{error}</Typography>
                }
                <ContainerLink>
                    <Link onClick={()=>handleFormSwitch(FormEnum.recover)}  underline='hover'>
                        <Typography variant='body2'>Esqueceu sua senha?</Typography>
                    </Link>
                </ContainerLink>
                <Button type='submit' color='primary' disabled={mutationLogin.isLoading } fullWidth>
                    {mutationLogin.isLoading ? <CircularProgress size={24} color='inherit'/> : 'Entrar'}
                </Button>

                {!preConta && isRegister &&
                    <Typography variant='body2' align='center'>Não é membro? <Link onClick={()=>handleFormSwitch(FormEnum.register)} underline='hover'>Cadastre-se</Link></Typography>
                }


                <DividerSfe textAlign='center'>
                    <Typography variant='body2'>ou</Typography>
                </DividerSfe>
                <ContainerSocial>
                    <GoogleLogin
                        size='medium'
                        onSuccess={onSuccessLoginGoogle}
                        shape='pill'
                        logo_alignment='center'
                        text='continue_with'
                        width={289}
                    />
                <FacebookLogin
                        scope="public_profile,email,user_birthday,user_location"
                        onSuccess={onSuccessLoginFacebook}
                    >
                        <Icon icon="mdiFacebook" size='20px' color='#0e5b9e'/>
                        Continuar com o Facebook
                    </FacebookLogin>
                </ContainerSocial>


            <Termos href={`${dominioSFE}/privacy`} target="_blank" underline="hover" variant='body2'>
                Termos de serviço e política de privacidade
            </Termos>
            </Form>
        </>


    )
}