"use client";
import React, {
  useContext,
  useMemo,
  useEffect,
  useState,
  JSX,
  useCallback
} from "react";
import localforage from 'localforage';

// import { useSession } from "next-auth/react";
import { KEYVALUEPAIR } from "@/types/interfaces";
import { useCommonReducer } from "./reducer";
import { useNavigationEvent } from "./routeLoader";
import { SuspenseLoader } from "./Loader";
import Cookies from "js-cookie";
import { useRequest } from "./request";
interface CONTEXTVALUE {
  alert: () => void;
  // role: string;
  // sessionLogout: () => void;
  // getSession: {
  //   [key: string]: string;
  // } & {
  //   permission?: Permission;
  // };
  // deviceInfo: any;
  userDetail: UserDetail | null;
  setUserDetail: React.Dispatch<React.SetStateAction<UserDetail | null>>;
  state: { [key: string]: unknown };
  dispatch: React.Dispatch<KEYVALUEPAIR>;
  searchState: {
    searchQuery: string;
    isLoader: boolean;
  };
  handleSidebarToggler: (toggleVal: boolean) => void;
  sideBarToggle: boolean;
  setSearchState: React.Dispatch<
    React.SetStateAction<{
      searchQuery: string;
      isLoader: boolean;
    }>
  >;
}

interface UserDetail {
  id: number;
  account_number: string;
  name: string;
  business_name: string;
  leads_per_day: number;
  landline_number: string;
  mobile_number: string;
  second_mobile_number: string;
  business_address: string;
  business_address_line_two: string;
  business_post_code: string;
  business_district_code: string;
  business_area_code: string;
  company_name: string;
  company_number: string;
  company_vat_number: string;
  company_address: string;
  company_address_line_two: string;
  company_post_code: string;
  person_significate_control: string;
  balance: string;
  minimum_account_balance: number;
  suspend_unsuspend_status: number;
  email: string;
  mobile: string;
  forgot_password_token: string;
  profile_image: string;
  status: number;
  reason_id: number;
  is_pause_admin: number;
  nature_id: number;
  pause_unpause_status: number;
  permanent_active_action: number;
  created_at: string;
  areas?: Array<{ id: number; code: string }>;
}

interface Props {
  children: JSX.Element | JSX.Element[] | React.ReactNode;
  // session: any;
}

const LOCAL_STORAGE_KEY = "app_state";
const AppContext = React.createContext<CONTEXTVALUE | null>(null);

export const AppProvider = ({ children }: Props) => {
  const { dispatch, state } = useCommonReducer();
  const [userDetail, setUserDetail] = useState<UserDetail | null>(null);
  const [sideBarToggle, setSideBarToggle] = useState<boolean>(false);
  const { request } = useRequest();
  const token = Cookies.get("accessToken");

  useEffect(() => {
    let isMounted = true;

    (async () => {
      try {
        const storedState = await localforage.getItem<typeof state>(LOCAL_STORAGE_KEY);
        if (storedState && isMounted) {
          dispatch(storedState);
        }
      } catch (error) {
        console.error("Error reading state from localforage", error);
      }
    })();

    return () => {
      isMounted = false;
    };
  }, [dispatch]);

  useEffect(() => {
    localforage
      .setItem(LOCAL_STORAGE_KEY, state)
      .catch(error => console.error("Error saving state to localforage", error));
  }, [state]);


  const [searchState, setSearchState] = useState({
    searchQuery: "",
    isLoader: false
  });

  const { isLoading } = useNavigationEvent();

  const getUserDetail = useCallback(async () => {
    if (!token) return;
    try {
      const res = await request("GET_PROFILE");

      //@ts-expect-error res.data is not defined in the state
      setUserDetail(res.data);
    } catch (error) {
      console.log(error);
      return null;
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const handleSidebarToggler = (toggleVal: boolean) => {
    const body: HTMLBodyElement = document.body as HTMLBodyElement;

    if (toggleVal) {
      body.classList.add("sidebar-active");
    } else {
      body.classList.remove("sidebar-active");
    }
    setSideBarToggle(toggleVal);
  };

  useEffect(() => {
    getUserDetail();
  }, [getUserDetail]);

  const value: CONTEXTVALUE = useMemo(() => {
    return {
      alert: () => console.log("Alert from CONTEXTVALUE"),
      state: state,
      dispatch,
      userDetail,
      setUserDetail,
      handleSidebarToggler,
      sideBarToggle,
      searchState,
      setSearchState
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [state, searchState, userDetail, sideBarToggle]);

  return (
    <AppContext.Provider value={value}>
      {isLoading ? <SuspenseLoader /> : children}
    </AppContext.Provider>
  );
};

export function useApp() {
  const context = useContext(AppContext);
  if (context === null) {
    throw new Error("useApp must be used within an AppProvider");
  }
  return context;
}
