import { createContext, useContext, useState } from "react"
import { CreateAccount } from "../../interfaces/services/ICreateUser";
import { newCreateAccount, NewCreateAccountProps } from "../../utils/createAccount";
import { FacebookResponse } from "../../interfaces/services/IFacebookResponse";
import { inverterData } from "../../utils/Date";

interface PayloadGoogle {
    iss: string,
    azp: string
    aud: string,
    sub: string,
    email: string,
    email_verified: boolean,
    nbf: number,
    name: string,
    picture: string,
    given_name: string,
    family_name: string,
    locale: string,
    iat: number,
    exp: number,
    jti: string

}

export enum Social {
    Google,
    Facebook
}
type TokenSocial = {
    [Social.Google]: string
    [Social.Facebook]: FacebookResponse
}

interface SocialTokenContextProps {
    setToken: <T extends Social>(token: TokenSocial[T], social: Social) => void
    getPayload: () => CreateAccount
}

const SocialTokenContext = createContext<SocialTokenContextProps>({
    setToken: () => {},
    getPayload: ()=>(newCreateAccount({}))
});

interface SocialTokenProviderProps {
    children: React.ReactNode;
}
export const SocialTokenProvider = ({ children }: SocialTokenProviderProps) => {
    const [googleCredential, setGoogleCredential] = useState<null | string>(null)
    const [FacebookCredential, setFacebookCredential] = useState<null | FacebookResponse>(null)

    const setToken = <T extends Social>(token:TokenSocial[T], social: T) => {
        switch (social) {
            case Social.Google:
                setGoogleCredential(token as string);
                break;
            case Social.Facebook:
                setFacebookCredential(token as FacebookResponse);
                break;
            default:
                 console.error('Social não implementado');
                break;
        }
    }

    const getPayload = () => {
        let cargaUtil:NewCreateAccountProps = {}
        if(googleCredential){
            const payload:PayloadGoogle = JSON.parse(window.atob(googleCredential.split('.')[1]));
            cargaUtil = {
                nome: payload.given_name,
                sobrenome: payload.family_name,
                email: payload.email,
                avatar:payload.picture,
                googleSub: payload.sub
            }
        }

        if(FacebookCredential){
            cargaUtil = {
                nome: FacebookCredential.first_name,
                sobrenome: FacebookCredential.last_name,
                email: FacebookCredential.email,
                avatar: FacebookCredential.picture.data.url,
                nascimento: inverterData(FacebookCredential.birthday),
                facebookUserId: FacebookCredential.id
            }
        }

        return newCreateAccount(cargaUtil)

    }

    return (
        <SocialTokenContext.Provider value={{ setToken, getPayload  }}>
            {children}
        </SocialTokenContext.Provider>
    )
}

export const useSocialTokenContext = () => {
    return useContext<SocialTokenContextProps>(SocialTokenContext);
};