import { create } from 'zustand';
import { useShallow } from 'zustand/react/shallow';

import { rpcCache } from '@/api/cache';
import type {
  CollectionRelationType,
  InitACPTType,
} from '@/api/types';
import type {
  CollectionViewProps,
  DialogStackItem,
} from '@/types/dialog';
import { EventEmitter } from '@/utils/event';

export type Theme = 'light' | 'dark' | 'system';

export interface AppConfig extends InitACPTType {
    color: string;
    isDarkTheme: boolean;
    dialogStack: DialogStackItem[];
    openDialog: (props: CollectionViewProps) => void;
    closeDialog: (modalKey?: string) => void;
    initLoaded: boolean;
    focusDialogKey: string | undefined;
    toggleTheme: () => void;
    openTableDialog: (params: CollectionRelationType & { ids: string[] }) => void;
    hideTips: boolean;
    setHideTips: (hideTips: boolean) => void;
}

const getFocusDialogKey = (dialogStack: DialogStackItem[]): string | undefined => {
    if (dialogStack.length === 0) {
        return undefined;
    }
    const last = dialogStack[dialogStack.length - 1];
    if (last.view) {
        return last.view.modalKey;
    }
    if (last.table) {
        return last.table.modalKey;
    }
    return undefined;
};

const applyThemeToDom = (isDarkTheme: boolean) => {
    const theme = isDarkTheme ? 'dark' : 'light';
    const root = window.document.documentElement;
    root.classList.remove('light', 'dark');
    root.classList.add(theme);
    localStorage.setItem('_theme', theme);
};

const applyColorToDom = (color?: string) => {
    if (color) {
        document.documentElement.style.setProperty('--color-primary', color);
        document.documentElement.style.setProperty('--k-color-primary', color);
    }
};

interface AppConfigStoreState {
    isMobile: boolean;
    setIsMobile: (isMobile: boolean) => void;
    isIOS: boolean;
    hideTips: boolean;
    setHideTips: (hideTips: boolean) => void;
    data: InitACPTType;
    initLoaded: boolean;
    initStarted: boolean;
    isDarkTheme: boolean;
    dialogStack: DialogStackItem[];
    focusDialogKey: string | undefined;
    loadInit: () => void;
    toggleTheme: () => void;
    openDialog: (props: CollectionViewProps) => void;
    openTableDialog: (params: CollectionRelationType & { ids: string[] }) => void;
    closeDialog: (modalKey?: string) => void;
}

const useAppConfigStore = create<AppConfigStoreState>((set, get) => ({
    isIOS: /iPad|iPhone|iPod/.test(navigator.userAgent),
    isMobile: typeof window !== 'undefined' ? window.innerWidth < 768 : false,
    setIsMobile: (isMobile: boolean) => set({ isMobile }),
    hideTips: typeof localStorage !== 'undefined' && localStorage.getItem('hideTips') === 'true',
    setHideTips: (hideTips: boolean) => {
        localStorage.setItem('hideTips', hideTips.toString());
        set({ hideTips });
    },
    data: {},
    initLoaded: false,
    initStarted: false,
    isDarkTheme: typeof localStorage !== 'undefined' && localStorage.getItem('_theme') === 'dark',
    dialogStack: [],
    focusDialogKey: undefined,
    loadInit: () => {
        if (get().initStarted) {
            return;
        }
        set({ initStarted: true });
        rpcCache.init().then((response) => {
            if (response?.result) {
                set({ data: response.result ?? {}, initLoaded: true });
            }
        });
    },
    toggleTheme: () => set((state) => ({ isDarkTheme: !state.isDarkTheme })),
    openDialog: (props: CollectionViewProps) => {
        set((state) => {
            const dialogStack: DialogStackItem[] = [
                ...state.dialogStack,
                {
                    view: {
                        ...props,
                        modalKey: `collection_view_${props.collection}_${props._id ?? 'create'}_${props.clonedFrom ?? ''}`,
                    },
                },
            ];
            return {
                dialogStack,
                focusDialogKey: getFocusDialogKey(dialogStack),
            };
        });
    },
    openTableDialog: (params: CollectionRelationType & { ids: string[] }) => {
        set((state) => {
            const dialogStack: DialogStackItem[] = [
                ...state.dialogStack,
                {
                    table: {
                        collection: params.collection!,
                        defaultFilter: {
                            [params.key!]: {
                                in: params.ids,
                            },
                        },
                        modalKey: `collection_table_${params.collection}_${JSON.stringify(params.key) ?? ''}`,
                    },
                },
            ];
            return {
                dialogStack,
                focusDialogKey: getFocusDialogKey(dialogStack),
            };
        });
    },
    closeDialog: (modalKey?: string) => {
        if (!modalKey) {
            return;
        }


        EventEmitter.execute("updateCollectionData");

        set((state) => {
            const dialogStack = state.dialogStack.filter(
                (item) => item.view?.modalKey !== modalKey && item.table?.modalKey !== modalKey,
            );
            return {
                dialogStack,
                focusDialogKey: getFocusDialogKey(dialogStack),
            };
        });
    },
}));

if (typeof window !== 'undefined') {
    applyThemeToDom(useAppConfigStore.getState().isDarkTheme);

    window.addEventListener('resize', () => {
        useAppConfigStore.setState({ isMobile: window.innerWidth < 768 });
    });

    useAppConfigStore.subscribe((state, prevState) => {
        if (state.isDarkTheme !== prevState.isDarkTheme) {
            applyThemeToDom(state.isDarkTheme);
        }
        if (state.data.color !== prevState.data.color) {
            applyColorToDom(state.data.color);
        }
    });
}

export function useAppConfig(): AppConfig {
    return useAppConfigStore(
        useShallow((state) => ({
            ...state.data,
            color: state.data.color ?? '#000000',
            initLoaded: state.initLoaded,
            isDarkTheme: state.isDarkTheme,
            dialogStack: state.dialogStack,
            focusDialogKey: state.focusDialogKey,
            toggleTheme: state.toggleTheme,
            openTableDialog: state.openTableDialog,
            openDialog: state.openDialog,
            closeDialog: state.closeDialog,
            hideTips: state.hideTips,
            setHideTips: state.setHideTips,
        })),
    );
}

export default useAppConfigStore;
