import { jsx as _jsx } from "react/jsx-runtime";
import React, { createContext, useContext, useEffect, useMemo, useState, } from "react";
import { themes, defaultTheme } from "./presets";
const ThemeContext = createContext(undefined);
const toKebabCase = (value) => value.replace(/([A-Z])/g, "-$1").toLowerCase();
const buildThemeResetStyles = (theme) => {
    const cssVariables = {
        "--flysoft-theme-name": theme.name,
    };
    Object.entries(theme.colors).forEach(([key, value]) => {
        cssVariables[`--flysoft-${toKebabCase(key)}`] = value;
    });
    Object.entries(theme.shadows).forEach(([key, value]) => {
        cssVariables[`--flysoft-shadow-${key}`] = value;
    });
    Object.entries(theme.radius).forEach(([key, value]) => {
        cssVariables[`--flysoft-radius-${key}`] = value;
    });
    Object.entries(theme.spacing).forEach(([key, value]) => {
        cssVariables[`--flysoft-spacing-${key}`] = value;
    });
    Object.entries(theme.fonts).forEach(([key, value]) => {
        cssVariables[`--flysoft-font-${key}`] = value;
    });
    return {
        color: theme.fonts.colorDefault ?? theme.colors.textPrimary,
        //backgroundColor: theme.colors.bgDefault,
        fontFamily: theme.fonts.default,
        fontSize: theme.fonts.sizeDefault,
        lineHeight: "1.5",
        ...cssVariables,
    };
};
export const ThemeProvider = ({ children, initialTheme = "light", storageKey = "flysoft-theme", forceInitialTheme = false, }) => {
    // Almacenar el tema inicial para poder resetear a él
    const getInitialTheme = () => {
        if (typeof initialTheme === "string") {
            return themes[initialTheme] || defaultTheme;
        }
        return initialTheme;
    };
    const [currentTheme, setCurrentTheme] = useState(() => {
        // Si forceInitialTheme es true, usar siempre el initialTheme
        if (forceInitialTheme) {
            return getInitialTheme();
        }
        // Try to get theme from localStorage
        if (typeof window !== "undefined") {
            const savedTheme = localStorage.getItem(storageKey);
            if (savedTheme) {
                if (themes[savedTheme]) {
                    return themes[savedTheme];
                }
                // Try to parse as custom theme
                try {
                    const parsed = JSON.parse(savedTheme);
                    if (parsed.name && parsed.colors) {
                        return parsed;
                    }
                }
                catch {
                    // Invalid JSON, fallback to default
                }
            }
        }
        // Handle initialTheme prop
        return getInitialTheme();
    });
    const [currentThemeName, setCurrentThemeName] = useState(currentTheme.name);
    // Function to apply theme to CSS variables
    const applyThemeToCSS = (theme) => {
        if (typeof document === "undefined")
            return;
        const root = document.documentElement;
        // Apply color variables
        Object.entries(theme.colors).forEach(([key, value]) => {
            const cssVarName = `--flysoft-${key
                .replace(/([A-Z])/g, "-$1")
                .toLowerCase()}`;
            root.style.setProperty(cssVarName, value);
        });
        // Apply shadow variables
        Object.entries(theme.shadows).forEach(([key, value]) => {
            const cssVarName = `--flysoft-shadow-${key}`;
            root.style.setProperty(cssVarName, value);
        });
        // Apply radius variables
        Object.entries(theme.radius).forEach(([key, value]) => {
            const cssVarName = `--flysoft-radius-${key}`;
            root.style.setProperty(cssVarName, value);
        });
        // Apply spacing variables
        Object.entries(theme.spacing).forEach(([key, value]) => {
            const cssVarName = `--flysoft-spacing-${key}`;
            root.style.setProperty(cssVarName, value);
        });
        // Apply font variables
        Object.entries(theme.fonts).forEach(([key, value]) => {
            const cssVarName = `--flysoft-font-${key}`;
            root.style.setProperty(cssVarName, value);
        });
        // Set theme name as data attribute for CSS targeting
        root.setAttribute("data-theme", theme.name);
        // Apply background and text colors to body for better integration
        const body = document.body;
        if (body) {
            //body.style.backgroundColor = theme.colors.bgDefault;
            body.style.color = theme.colors.textPrimary;
            body.style.fontFamily = theme.fonts.default;
        }
    };
    // Function to set theme
    const setTheme = (theme) => {
        let newTheme;
        if (typeof theme === "string") {
            if (themes[theme]) {
                newTheme = themes[theme];
            }
            else {
                console.warn(`Theme "${theme}" not found, falling back to default`);
                newTheme = defaultTheme;
            }
        }
        else {
            newTheme = theme;
        }
        setCurrentTheme(newTheme);
        setCurrentThemeName(newTheme.name);
        // Save to localStorage
        if (typeof window !== "undefined") {
            localStorage.setItem(storageKey, JSON.stringify(newTheme));
        }
        // Apply to CSS
        applyThemeToCSS(newTheme);
    };
    // Function to reset to initial theme (the one passed as initialTheme prop)
    const resetToDefault = () => {
        setTheme(getInitialTheme());
    };
    // Apply theme on mount and when theme changes
    useEffect(() => {
        applyThemeToCSS(currentTheme);
    }, [currentTheme]);
    // Check if current theme is dark
    const isDark = currentTheme.name === "dark";
    const themeResetStyles = useMemo(() => buildThemeResetStyles(currentTheme), [currentTheme]);
    const value = {
        theme: currentTheme,
        setTheme,
        currentThemeName,
        availableThemes: Object.keys(themes),
        resetToDefault,
        isDark,
    };
    return (_jsx(ThemeContext.Provider, { value: value, children: _jsx("div", { className: "flysoft-theme-reset", style: themeResetStyles, "data-theme": currentTheme.name, children: children }) }));
};
// Hook to use theme context
// eslint-disable-next-line react-refresh/only-export-components
export const useTheme = () => {
    const context = useContext(ThemeContext);
    if (context === undefined) {
        throw new Error("useTheme must be used within a ThemeProvider");
    }
    return context;
};
// Hook to check if theme context is available
// eslint-disable-next-line react-refresh/only-export-components
export const useThemeContext = () => {
    const context = useContext(ThemeContext);
    return context !== undefined;
};
