import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import themeConfig from '../theme.config';
import {
    applyColorSchemeToDom,
    clearLegacyThemeKeys,
    ColorSchemeId,
    DEFAULT_COLOR_SCHEME,
    getColorSchemePreset,
    isLoggedInUserId,
    isLightOnlyScheme,
    migrateLegacyThemePreferences,
    readUserThemePreferences,
    ThemePreferences,
    writeUserThemePreferences,
} from '../lib/theme-colors';

type ThemeState = {
    isDarkMode: boolean;
    sidebar: boolean;
    theme: string;
    menu: string;
    layout: string;
    rtlClass: string;
    animation: string;
    navbar: string;
    locale: string;
    semidark: boolean;
    colorScheme: ColorSchemeId;
    languageList: { code: string; name: string }[];
    pageTitle: string;
};

const initialState: ThemeState = {
    isDarkMode: false,
    sidebar: false,
    theme: themeConfig.theme,
    menu: themeConfig.menu,
    layout: themeConfig.layout,
    rtlClass: themeConfig.rtlClass,
    animation: themeConfig.animation,
    navbar: themeConfig.navbar,
    locale: themeConfig.locale,
    semidark: themeConfig.semidark,
    colorScheme: (themeConfig.colorScheme as ColorSchemeId) || DEFAULT_COLOR_SCHEME,
    languageList: [
        { code: 'zh', name: 'Chinese' },
        { code: 'da', name: 'Danish' },
        { code: 'en', name: 'English' },
        { code: 'fr', name: 'French' },
        { code: 'de', name: 'German' },
        { code: 'el', name: 'Greek' },
        { code: 'hu', name: 'Hungarian' },
        { code: 'it', name: 'Italian' },
        { code: 'ja', name: 'Japanese' },
        { code: 'pl', name: 'Polish' },
        { code: 'pt', name: 'Portuguese' },
        { code: 'ru', name: 'Russian' },
        { code: 'es', name: 'Spanish' },
        { code: 'sv', name: 'Swedish' },
        { code: 'tr', name: 'Turkish' },
        { code: 'ae', name: 'Arabic' },
    ],
    pageTitle: '',
};

function getCurrentUserId(): string | null {
    if (typeof localStorage === 'undefined') return null;
    return localStorage.getItem('user');
}

function snapshotPreferences(state: ThemeState): ThemePreferences {
    return {
        theme: state.theme,
        menu: state.menu,
        layout: state.layout,
        rtlClass: state.rtlClass,
        animation: state.animation,
        navbar: state.navbar,
        semidark: state.semidark,
        colorScheme: state.colorScheme,
    };
}

function persistPreferences(state: ThemeState): void {
    const userId = getCurrentUserId();
    if (!isLoggedInUserId(userId)) return;
    writeUserThemePreferences(userId, snapshotPreferences(state));
}

function applyDarkModeClass(isDarkMode: boolean): void {
    if (typeof document === 'undefined') return;
    if (isDarkMode) {
        document.querySelector('body')?.classList.add('dark');
    } else {
        document.querySelector('body')?.classList.remove('dark');
    }
}

function resolveIsDarkMode(theme: string): boolean {
    if (theme === 'light') return false;
    if (theme === 'dark') return true;
    if (typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches) {
        return true;
    }
    return false;
}

function applyThemeMode(state: ThemeState, theme: string): void {
    state.theme = theme;
    state.isDarkMode = resolveIsDarkMode(theme);
    applyDarkModeClass(state.isDarkMode);
}

function lockLightOnlyMode(state: ThemeState): void {
    if (!isLightOnlyScheme(state.colorScheme)) return;
    state.semidark = false;
    applyThemeMode(state, 'light');
}

function applyColorScheme(state: ThemeState, colorScheme: string): void {
    const preset = getColorSchemePreset(colorScheme);
    state.colorScheme = preset.id;
    applyColorSchemeToDom(preset.id);
    lockLightOnlyMode(state);
}

const themeConfigSlice = createSlice({
    name: 'theme',
    initialState,
    reducers: {
        toggleTheme(state, { payload }: PayloadAction<string | undefined>) {
            if (isLightOnlyScheme(state.colorScheme)) {
                applyThemeMode(state, 'light');
                persistPreferences(state);
                return;
            }
            const next = payload || state.theme;
            applyThemeMode(state, next);
            persistPreferences(state);
        },
        toggleMenu(state, { payload }: PayloadAction<string | undefined>) {
            const next = payload || state.menu;
            state.sidebar = false;
            state.menu = next;
            persistPreferences(state);
        },
        toggleLayout(state, { payload }: PayloadAction<string | undefined>) {
            const next = payload || state.layout;
            state.layout = next;
            persistPreferences(state);
        },
        toggleRTL(state, { payload }: PayloadAction<string | undefined>) {
            const next = payload || state.rtlClass;
            state.rtlClass = next;
            document.querySelector('html')?.setAttribute('dir', state.rtlClass || 'ltr');
            persistPreferences(state);
        },
        toggleAnimation(state, { payload }: PayloadAction<string | undefined>) {
            const next = (payload || state.animation || '').trim();
            state.animation = next;
            persistPreferences(state);
        },
        toggleNavbar(state, { payload }: PayloadAction<string | undefined>) {
            const next = payload || state.navbar;
            state.navbar = next;
            persistPreferences(state);
        },
        toggleSemidark(state, { payload }: PayloadAction<boolean | string | undefined>) {
            if (isLightOnlyScheme(state.colorScheme)) {
                state.semidark = false;
                persistPreferences(state);
                return;
            }
            state.semidark = payload === true || payload === 'true';
            persistPreferences(state);
        },
        toggleColorScheme(state, { payload }: PayloadAction<string | undefined>) {
            applyColorScheme(state, payload || state.colorScheme);
            persistPreferences(state);
        },
        toggleLocale(state, { payload }: PayloadAction<string | undefined>) {
            const next = payload || state.locale;
            localStorage.setItem('i18nextLng', next);
            state.locale = next;
        },
        toggleSidebar(state) {
            state.sidebar = !state.sidebar;
        },
        setPageTitle(state, { payload }: PayloadAction<string | undefined>) {
            const next = payload || state.pageTitle;
            localStorage.setItem('pageTitle', next);
            state.pageTitle = next;
            document.title = `${next} | AURUM LAB`;
        },
        /** Load prefs for a logged-in user (migrates legacy keys once). */
        loadUserTheme(state, { payload }: PayloadAction<string | undefined>) {
            const userId = payload || getCurrentUserId();
            if (!isLoggedInUserId(userId)) {
                applyColorScheme(state, DEFAULT_COLOR_SCHEME);
                return;
            }

            let prefs = readUserThemePreferences(userId);
            if (!prefs) {
                prefs = migrateLegacyThemePreferences(userId) || {};
                if (Object.keys(prefs).length > 0) {
                    writeUserThemePreferences(userId, {
                        theme: prefs.theme || themeConfig.theme,
                        menu: prefs.menu || themeConfig.menu,
                        layout: prefs.layout || themeConfig.layout,
                        rtlClass: prefs.rtlClass || themeConfig.rtlClass,
                        animation: prefs.animation ?? themeConfig.animation,
                        navbar: prefs.navbar || themeConfig.navbar,
                        semidark: typeof prefs.semidark === 'boolean' ? prefs.semidark : themeConfig.semidark,
                        colorScheme: prefs.colorScheme || DEFAULT_COLOR_SCHEME,
                    });
                    clearLegacyThemeKeys();
                }
            }

            applyThemeMode(state, prefs.theme || themeConfig.theme);
            state.menu = prefs.menu || themeConfig.menu;
            state.layout = prefs.layout || themeConfig.layout;
            state.rtlClass = prefs.rtlClass || themeConfig.rtlClass;
            document.querySelector('html')?.setAttribute('dir', state.rtlClass || 'ltr');
            state.animation = prefs.animation ?? themeConfig.animation;
            state.navbar = prefs.navbar || themeConfig.navbar;
            state.semidark = typeof prefs.semidark === 'boolean' ? prefs.semidark : themeConfig.semidark;
            applyColorScheme(state, prefs.colorScheme || DEFAULT_COLOR_SCHEME);
        },
        /** Reset to theme.config defaults (used on logout). */
        resetThemeToDefaults(state) {
            applyThemeMode(state, themeConfig.theme);
            state.menu = themeConfig.menu;
            state.layout = themeConfig.layout;
            state.rtlClass = themeConfig.rtlClass;
            document.querySelector('html')?.setAttribute('dir', state.rtlClass || 'ltr');
            state.animation = themeConfig.animation;
            state.navbar = themeConfig.navbar;
            state.semidark = themeConfig.semidark;
            applyColorScheme(state, DEFAULT_COLOR_SCHEME);
            state.sidebar = false;
        },
    },
});

export const {
    toggleTheme,
    toggleMenu,
    toggleLayout,
    toggleRTL,
    toggleAnimation,
    toggleNavbar,
    toggleSemidark,
    toggleColorScheme,
    toggleLocale,
    toggleSidebar,
    setPageTitle,
    loadUserTheme,
    resetThemeToDefaults,
} = themeConfigSlice.actions;

export default themeConfigSlice.reducer;
