/**
 * 
 * Store as an initial local store for the app
 * 
 * All the data that is needed accross the app like user, openProperties etc goes from here.
 * 
 */

import React, { useEffect, useState, createContext, useReducer } from 'react';

import FirebaseUtils from './utils/firebase.utils';

import useDeviceDetect from './hooks/device-detect';

import ApiUtils from './utils/api/api.utils';

import SettingsUtil from './utils/setting.utils';

import { GlobalHotKeys } from 'react-hotkeys';

import { Location } from './utils';

import { I18nextProvider } from 'react-i18next';

import i18n from '../lib/i18n';

import themes from '../lib/pages/profile/themes.json';

import { ConfigProvider } from 'antd';

// import { initializeFirebasePushNotification } from './push-notification';

/**
 * Initial State to be stored
 * accross the app
 * 
 * For now maintaining only user data 
 * 
 * #todo Compare the setup with state manager utility 
 * 
 */

/**
 * Code to get stored theme from local storage, if the localstorage doesn't have any store theme, it will return first value of themes array
 * 
 * @returns 
 */
const initialTheme = () => {
    try {
    //  manage theme with env
      const isEnvThemeTrue = process.env.REACT_APP_THEME === 'true';
      console.log('REACT_APP_THEME:', isEnvThemeTrue);
      if (isEnvThemeTrue) {
        // Always return 'nura' theme, ignore saved theme
        return themes.find(theme => theme.name === 'nura') ;
      }
  
      // Check saved theme
      const savedTheme = localStorage.getItem('selectedTheme');
      if (savedTheme) {
        return JSON.parse(savedTheme);
      }
  
      // Fallback to default
      return themes[0];
    } catch (e) {
      console.error('Error loading theme:', e);
      return themes[0];
    }
  };
  

const initialState = {
    defaultBranch: {

    },
    theme: initialTheme() // Set the initial theme from themes.json
};

/**
 * Context for sharing state accross app
 */
export const GlobalContext = createContext(initialState);

let app = {};

/**
 * Provider links the reducer and context
 * 
 * @param {*} param0 
 * @returns 
 */
export const GlobalProvider = ({ children, CustomModels, appSettings: settings }) => {

    // console.log("Setting up store");

    const [branches, setBranches] = useState([]);

    const [state, dispatch] = useReducer(AppReducer, initialState)

    console.log(state);

    const { isMobile } = useDeviceDetect();

    useEffect(() => {

        bootApplication();

        return () => {

        };

    }, [])

    /**
     * 
     */
    function bootApplication() {

        if (process.env.REACT_APP_PRIMARY_BACKEND === 'firebase') {

            bootFirebaseApplication();

        } else {

            bootMainApplication();

        }
    }

    /**
     * 
     */
    function bootFirebaseApplication() {

        return FirebaseUtils.connect().then((app, database) => {

            app = app;

            return FirebaseUtils.getAuthStatus().then((result) => {
                // console.log(result);

                if (result) {

                    // initializeFirebasePushNotification(result);

                    let userInfo = {
                        dms: {},
                        locations: [],
                        ...result,
                        ...{ loggedCheckDone: true }
                    }

                    // if (result.role && result.role.name === 'admin') {

                    userInfo.isAdmin = true;

                    // }


                    dispatch({ type: 'user', payload: userInfo });

                    localStorage.setItem('userInfo', JSON.stringify(userInfo));

                    // dispatch({ type: 'user', payload: { ...result, ...{ loggedCheckDone: true } } })
                } else {

                    dispatch({ type: 'user', payload: { ...{ loggedCheckDone: true } } })

                }
            }).catch((error) => {
                console.log(error);
            })
        })
    }


    function bootMainApplication() {

        // If there is any token present in url the following will be exicute
        let token;
        // Get the query string from the current window location
        let string = window.location.search;

        const substring = "token";
        // Check if the query string contains the specified substring
        // if (string.includes(substring)) {

        //     // If substring is found, calculate the start index of the token
        //     const tokenStartIndex = string.indexOf("token=") + "token=".length;

        //     // Extract the token from the query string
        //     token = string.substring(tokenStartIndex);

        // }

        ApiUtils.getAuthStatus({ settings, token }).then((response) => {

            if (response.statusCode === 401) {

                dispatch({ type: 'user', payload: { ...{ loggedCheckDone: true } } });

                Location.navigate({ url: '/login' });

            } else {

                // @todo Below is a temporary fix to avoid update of nura desk 
                // at the time of the update for syncing core application 
                // But ideally the repsonse should always be under result . 
                // So when we choose to have nura api to use bootstrap core , 
                // Then may be we can have this synced
                let userData = {};

                if (response.result) {

                    userData = response.result;

                } else {

                    userData = response;

                }

                let userInfo = {
                    ...userData,
                    ...{ loggedCheckDone: true },
                };

                if (userData.name && ['Tech Team', 'Developer', 'admin'].indexOf(response.name) !== -1) {

                    userInfo.isAdmin = true;

                }

                localStorage.setItem("userInfo", JSON.stringify(userInfo));

                // If there is token exist it is stored to localstorage
                if (token) {

                    localStorage.setItem("access_token", token);
                }

                dispatch({ type: 'user', payload: userInfo });
            }
        }).catch(() => {

            Location.navigate({ url: '/login' });

            dispatch({ type: 'user', payload: { ...{ loggedCheckDone: true } } });

        });

    }


    // Store that is accessible accross the app
    // let store = { user: state.user, slot: state.slot, dispatch: dispatch, selectedLocation: state.selectedLocation }
    let store = {
        app: app,
        user: state.user,
        dispatch: dispatch,
        twilio: state.twilio,
        isMobile,
        branches,
        defaultBranch: state.defaultBranch,
        CustomModels: CustomModels,
        selectedBranch: state.selectedBranch,
        kiosk: state.kiosk,
        state
    };

    // console.log(CustomModels);

    const { googleMapsAPIKey, mapOptions, googleMapsLibraries } = settings;

    useEffect(() => {

        localStorage.setItem('selectedTheme', JSON.stringify(state.theme));

    }, [state.theme]); // Sync theme changes to localStorage

    return (<SearchKeyboardListener>

        {/* <MapContainer googleMapsAPIKey={googleMapsAPIKey} mapOptions={mapOptions} googleMapsLibraries={googleMapsLibraries}> */}
        <I18nextProvider i18n={i18n}>
            <GlobalContext.Provider value={store}>
                {/* Use ConfigProvider to pass the theme stored in state */}
                <ConfigProvider

                    theme={{
                        token: {
                            "primaryColor": "#446AA9",


                            colorPrimary: '#ff4d4f',  // Red
                            colorBgBase: '#f5f5f5',   // Light Gray
                            colorText: '#000000',     // Black
                        },
                    }}

                // theme={{
                //     token: {
                //         ...state.theme.colors
                //     }
                // }}
                >
                    {children}
                </ConfigProvider>
            </GlobalContext.Provider>
        </I18nextProvider>

        {/* </MapContainer> */}

        {/* <ModalWrapper ref={(elem) => ModalManager.registerModal(elem)} /> */}

    </SearchKeyboardListener>)

}

/**
 * Reducer for managing the state
 * 
 * @param state 
 * @param action 
 */
export const AppReducer = (state, action) => {

    switch (action.type) {


        case 'app':

            return { ...state, app: action.payload };

        case 'kiosk':

            return { ...state, kiosk: action.payload };


        case 'twilio':

            return { ...state, twilio: action.payload };

        case 'user':
            return { ...state, user: action.payload };

        case 'slot':
            return { ...state, user: action.payload };

        case 'branches':
            return { ...state, branches: action.payload };

        case 'defaultBranch':
            return { ...state, defaultBranch: action.payload };

        case 'CustomModels':
            return { ...state, CustomModels: action.CustomModels };

        // # TODO Below Variable might be removed 
        case 'selectedLocation':
            localStorage.selectedLocation = JSON.stringify(action.payload);
            return { ...state, selectedLocation: action.payload };

        // Variable to store the selected branch for Nura
        case 'selectedBranch':

            localStorage.selectedBranch = JSON.stringify(action.payload);

            return { ...state, selectedBranch: action.payload };

        // to set theme for application
        case 'appTheme':

            return { ...state, theme: action.payload }


        default:
            return state;
    }
}

/**
 * Listens for keyboard to activate the spotlight search
 */
function SearchKeyboardListener({ children }) {


    const keyMap = {
        moveUp: 'Shift+B',
        spotlight: 'Shift+F'
    }


    const handlers = {

        // 'moveUp': (event) => this.toggleSideNav(this.state.sideNavExpanded),
        'spotlight': (event) => {

            // console.log(modalRef);
            // modalRef.current.openModal();
            SettingsUtil.openSpotlightModal();
        }
    }


    return (<>

        <GlobalHotKeys focused={true} attach={window} keyMap={keyMap} handlers={handlers}>

            {children}

        </GlobalHotKeys>
    </>)

}

