import { initializeApp } from "firebase/app";
import {
  getFirestore,
  Firestore,
  collection,
  addDoc,
  getDocs,
} from "firebase/firestore";
import React, { ReactNode } from "react";

import { FirebaseContext } from "./types";

const Context = React.createContext<FirebaseContext>({
  createRecord: undefined,
  getRecords: undefined,
  firebaseDB: undefined,
});
Context.displayName = "FirebaseContext";

export const useFirebase = () => React.useContext(Context);

export const FirebaseProvider: React.FC<{ children?: ReactNode }> = ({
  children,
}) => {
  const [db, setDb] = React.useState<Firestore | null>(null);

  const firebaseConfig = {
    apiKey: "AIzaSyCsH-fhpvM9XbWcGHQmM7CHPuiOFQqqH0E",
    authDomain: "curated-cadb3.firebaseapp.com",
    projectId: "curated-cadb3",
    storageBucket: "curated-cadb3.appspot.com",
    messagingSenderId: "1012372832970",
    appId: "1:1012372832970:web:4a6df2896cc2571adfea33",
    measurementId: "G-EWBWFGMWJE",
  };

  React.useEffect(() => {
    initializeApp(firebaseConfig);
    const db = getFirestore();
    setDb(db);
  }, []);

  const handleAsync = React.useCallback(async (action: () => Promise<any>) => {
    try {
      const result = await action();
      return result;
    } catch (err) {
      if (err instanceof Error) {
        console.error(err);
      }
    }
  }, []);

  const createRecord = React.useCallback(
    async (collectionName: string, data: any) => {
      if (db) {
        const result = await handleAsync(async () => {
          const reference = await addDoc(collection(db, collectionName), data);
          return reference;
        });

        return result;
      }
    },
    [db, handleAsync]
  );

  const getRecords = React.useCallback(
    async (collectionName: string) => {
      if (db) {
        const result = await handleAsync(async () => {
          const reference = await getDocs(collection(db, collectionName));
          return reference;
        });

        return result;
      }
    },
    [db, handleAsync]
  );

  return (
    <Context.Provider
      value={{
        createRecord,
        getRecords,
        firebaseDB: db,
      }}
    >
      {children}
    </Context.Provider>
  );
};
