import React from "react";
import { useAuthState } from "react-firebase-hooks/auth";
import { emptyRequest, getRequest, postRequest } from "../constants/requests";
import { useHttp } from "./useHttp";
import { useApp } from "./useApp";
import { signInWithEmailAndPassword, signOut as signOutFirebase } from 'firebase/auth';
import { auth, firestore } from "../services/firebase";
import { message, Modal } from "antd";
import { ExclamationCircleOutlined } from "@ant-design/icons";
import { collection, getDocs, where, query } from "firebase/firestore";
import { TIPO_PROJECTO_FIREBASE, TIPO_PROJECTO_JWT } from "../constants";
const { REACT_APP_PROJECT: tipoProyecto } = process.env;

const AuthContext = React.createContext();
const empty = emptyRequest();

export function AuthProvider(props) {
  const { token, setToken } = useApp();
  const [sessionFb, sessionFbLoading, sessionFbError] = useAuthState(auth);
  const [userDoc, setUserDoc] = React.useState(null);
  const [sessionRequest, setSessionRequest] = React.useState(empty);
  const [agendaRequest, setAgendaRequest] = React.useState(empty);
  const [sessionJWT, sessionJWTLoading] = useHttp(sessionRequest);
  const [agendaResponse, agendaResponseLoading, agendaError] = useHttp(agendaRequest);
  console.log(sessionFb);
  const signIn = React.useCallback(async (email, password) => {
    try {
      if(tipoProyecto === TIPO_PROJECTO_FIREBASE){
        await signInWithEmailAndPassword(auth, email, password);
      } else {
        if(email !== "" && password !== "") {
          const req = postRequest("v1/iniciar-sesion", { correo: email, clave: password });
          setSessionRequest({ ...req });
        } 
      }
    } catch (e) {
      if(tipoProyecto === TIPO_PROJECTO_JWT){
        console.log(e)
      } else  {
        if( e.code === 'auth/wrong-password' || e.code === 'auth/user-not-found') {
          message.warning({
            content: 'Atención: Usuario/Contraseña son incorrectos.',
          });
        } else if ( e.code === 'auth/invalid-email' ) {
          message.warning({
            content: 'El correo electrónico no es válido.',
          });
        };
      }
    };
  }, []);

  const signOut = React.useCallback(async () => {
    try {
      Modal.confirm({
        title: 'Atención',
        icon: <ExclamationCircleOutlined />,
        content: '¿Estás seguro de que deseas cerrar sesión?',
        okText: 'Cerrar sesión',
        cancelText: 'Cancelar',
        onOk: async () => {
          if(tipoProyecto === TIPO_PROJECTO_FIREBASE) {
            await signOutFirebase( auth );
          } else {
            setToken(null)
            setSessionRequest(empty)
          }
          localStorage.clear();
          setAgendaRequest(empty);
        }
      });
    } catch (e) {
      console.error(e);
    }
  }, [setToken]);

  React.useEffect(() => {
    if(tipoProyecto === TIPO_PROJECTO_JWT) {
      if(sessionJWT && !sessionJWTLoading) {
        if(sessionJWT?.detalle) {
          setToken(sessionJWT?.detalle?.token)
        }
      }
    }
  }, [sessionJWT, sessionJWTLoading, setToken])

  React.useEffect(() => {
    if (token && tipoProyecto === TIPO_PROJECTO_JWT) {
      const agendaReq = getRequest("v1/perfil");
      setAgendaRequest(() => agendaReq);
    } else {
      setAgendaRequest(empty);
    }
  }, [token]);

  React.useEffect(() => {
    if(sessionFb) {
      setTimeout( async () => {
        const q = query(collection(firestore, "usuarios"), where('uid', '==', sessionFb?.uid));
        const querySnapshot = await getDocs(q)
        querySnapshot.forEach((doc) => {
          setUserDoc( doc.data() )
        })
      }, 0);
    }
  }, [sessionFb]);

  const memData = React.useMemo(() => {
    return {
      userDoc: tipoProyecto === TIPO_PROJECTO_FIREBASE ? userDoc : null,
      session: tipoProyecto === TIPO_PROJECTO_FIREBASE ? sessionFb : sessionJWT,
      sessionLoading: tipoProyecto === TIPO_PROJECTO_FIREBASE ? sessionFbLoading : sessionJWTLoading,
      user: tipoProyecto === TIPO_PROJECTO_FIREBASE ?  agendaResponse : agendaResponse && agendaResponse.resultado[0],
      userLoading: agendaResponseLoading,
      userError: agendaError || tipoProyecto === TIPO_PROJECTO_FIREBASE ? sessionFbError : null,
      signIn,
      signOut,
    };
  }, [
    userDoc,
    agendaError, 
    agendaResponse, 
    agendaResponseLoading, 
    sessionFb, 
    sessionFbError, 
    sessionFbLoading, 
    sessionJWT, 
    sessionJWTLoading, 
    signIn, 
    signOut
  ]);

  return <AuthContext.Provider value={memData} {...props} />;
}

export function useAuth() {
  const context = React.useContext(AuthContext);
  if (!context) {
    // eslint-disable-next-line no-throw-literal
    throw "error: auth context not defined.";
  }
  return context;
}