"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createThemeZero = exports.createThemeIcons = exports.createThemeColors = exports.darkTheme = exports.lightTheme = void 0;
exports.ThemeProvider = ThemeProvider;
exports.useTheme = useTheme;
exports.usePlatformTypography = usePlatformTypography;
exports.createThemedStyles = createThemedStyles;
const jsx_runtime_1 = require("react/jsx-runtime");
const portal_1 = require("@rn-primitives/portal");
const react_1 = require("react");
const react_native_1 = require("react-native");
const tokens_1 = require("./tokens");
const react_native_gesture_handler_1 = require("react-native-gesture-handler");
const toast_1 = require("../../components/ui/toast");
// Import pairify function for generating theme tokens
function pairify(obj, styleKeyPrefix) {
    const result = {};
    for (const [key, value] of Object.entries(obj)) {
        if (typeof value === "object" && value !== null && !Array.isArray(value)) {
            // For nested objects (like color scales), create another level
            result[key] = {};
            for (const [nestedKey, nestedValue] of Object.entries(value)) {
                result[key][nestedKey] = { [styleKeyPrefix]: nestedValue };
            }
        }
        else {
            // For simple values, create the style object directly
            result[key] = { [styleKeyPrefix]: value };
        }
    }
    return result;
}
// Create theme colors based on dark mode
const createThemeColors = (isDark, lightTheme, darkTheme, colorTheme) => {
    let baseColors;
    if (isDark && darkTheme) {
        // Use dark theme
        baseColors = isColorPalette(darkTheme)
            ? generateThemeColorsFromPalette(darkTheme, true)
            : darkTheme;
    }
    else if (!isDark && lightTheme) {
        // Use light theme
        baseColors = isColorPalette(lightTheme)
            ? generateThemeColorsFromPalette(lightTheme, false)
            : lightTheme;
    }
    else {
        // Fall back to default gray theme
        const defaultPalette = tokens_1.colors.neutral;
        baseColors = generateThemeColorsFromPalette(defaultPalette, isDark);
    }
    // Merge with custom color overrides if provided
    return {
        ...baseColors,
        ...colorTheme,
    };
};
exports.createThemeColors = createThemeColors;
// Create theme-aware zero tokens using pairify
const createThemeZero = (themeColors) => ({
    // Theme-aware colors using pairify
    bg: pairify(themeColors, "backgroundColor"),
    text: pairify(themeColors, "color"),
    border: {
        ...pairify(themeColors, "borderColor"),
        default: { borderColor: themeColors.border },
    },
    // Static design tokens
    shadow: {
        sm: tokens_1.shadows.sm,
        md: tokens_1.shadows.md,
        lg: tokens_1.shadows.lg,
        xl: tokens_1.shadows.xl,
    },
    // Common button styles
    button: {
        primary: {
            backgroundColor: themeColors.primary,
            borderWidth: 0,
            ...tokens_1.shadows.sm,
        },
        secondary: {
            backgroundColor: themeColors.secondary,
            borderWidth: 0,
        },
        outline: {
            backgroundColor: "transparent",
            borderWidth: 1,
            borderColor: themeColors.border,
        },
        ghost: {
            backgroundColor: "transparent",
            borderWidth: 0,
        },
    },
    // Input styles
    input: {
        base: {
            backgroundColor: themeColors.background,
            borderWidth: 1,
            borderColor: themeColors.border,
            borderRadius: tokens_1.borderRadius.md,
            paddingHorizontal: tokens_1.spacing[3],
            paddingVertical: tokens_1.spacing[3],
            minHeight: tokens_1.touchTargets.minimum,
        },
        focused: {
            borderColor: themeColors.ring,
            borderWidth: 2,
        },
        error: {
            borderColor: themeColors.destructive,
            borderWidth: 2,
        },
    },
    // Card styles
    card: {
        base: {
            backgroundColor: themeColors.card,
            borderRadius: tokens_1.borderRadius.lg,
            ...tokens_1.shadows.sm,
        },
    },
});
exports.createThemeZero = createThemeZero;
// Create theme icons based on colors
const createThemeIcons = (themeColors) => ({
    color: {
        default: themeColors.text,
        muted: themeColors.textMuted,
        primary: themeColors.primary,
        secondary: themeColors.secondary,
        destructive: themeColors.destructive,
        success: themeColors.success,
        warning: themeColors.warning,
    },
    size: {
        sm: 16,
        md: 20,
        lg: 24,
        xl: 32,
    },
});
exports.createThemeIcons = createThemeIcons;
// Create the theme context
const ThemeContext = (0, react_1.createContext)(null);
// Helper function to check if input is a ColorPalette or Theme["colors"]
function isColorPalette(input) {
    return "50" in input && "100" in input && "950" in input;
}
// Helper function to generate Theme["colors"] from ColorPalette
function generateThemeColorsFromPalette(palette, isDark) {
    return {
        background: isDark ? palette[950] : tokens_1.colors.white,
        foreground: isDark ? palette[50] : palette[950],
        card: isDark ? palette[900] : tokens_1.colors.white,
        cardForeground: isDark ? palette[50] : palette[950],
        popover: isDark ? palette[900] : tokens_1.colors.white,
        popoverForeground: isDark ? palette[50] : palette[950],
        primary: react_native_1.Platform.OS === "ios" ? tokens_1.colors.ios.systemBlue : tokens_1.colors.primary[500],
        primaryForeground: tokens_1.colors.white,
        secondary: isDark ? palette[800] : palette[100],
        secondaryForeground: isDark ? palette[50] : palette[900],
        muted: isDark ? palette[800] : palette[100],
        mutedForeground: isDark ? palette[400] : palette[500],
        accent: isDark ? palette[800] : palette[100],
        accentForeground: isDark ? palette[50] : palette[900],
        destructive: tokens_1.colors.destructive[700],
        destructiveForeground: tokens_1.colors.white,
        success: tokens_1.colors.success[700],
        successForeground: tokens_1.colors.white,
        warning: tokens_1.colors.warning[700],
        warningForeground: tokens_1.colors.white,
        info: tokens_1.colors.blue[700],
        infoForeground: isDark ? palette[50] : palette[900],
        border: isDark ? palette[500] + "30" : palette[200] + "30",
        input: isDark ? palette[800] : palette[200],
        ring: react_native_1.Platform.OS === "ios" ? tokens_1.colors.ios.systemBlue : tokens_1.colors.primary[500],
        text: isDark ? palette[50] : palette[950],
        textMuted: isDark ? palette[400] : palette[500],
        textDisabled: isDark ? palette[600] : palette[400],
    };
}
// Theme provider component
// Should be surrounded by SafeAreaProvider at the root
function ThemeProvider({ children, defaultTheme = "system", forcedTheme, colorTheme, lightTheme, darkTheme, }) {
    const systemColorScheme = (0, react_native_1.useColorScheme)();
    const [currentTheme, setCurrentTheme] = (0, react_1.useState)(defaultTheme);
    // Determine if dark mode should be active
    const isDark = (0, react_1.useMemo)(() => {
        if (forcedTheme === "light")
            return false;
        if (forcedTheme === "dark")
            return true;
        if (currentTheme === "light")
            return false;
        if (currentTheme === "dark")
            return true;
        if (currentTheme === "system")
            return systemColorScheme === "dark";
        return systemColorScheme === "dark";
    }, [forcedTheme, currentTheme, systemColorScheme]);
    // Create theme based on dark mode
    const theme = (0, react_1.useMemo)(() => {
        const themeColors = createThemeColors(isDark, lightTheme, darkTheme, colorTheme);
        return {
            colors: themeColors,
            spacing: tokens_1.spacing,
            borderRadius: tokens_1.borderRadius,
            typography: tokens_1.typography,
            shadows: tokens_1.shadows,
            touchTargets: tokens_1.touchTargets,
            animations: tokens_1.animations,
        };
    }, [isDark, lightTheme, darkTheme, colorTheme]);
    // Create theme-aware zero tokens
    const zero = (0, react_1.useMemo)(() => {
        return createThemeZero(theme.colors);
    }, [theme.colors]);
    // Create icon utilities
    const icons = (0, react_1.useMemo)(() => {
        return createThemeIcons(theme.colors);
    }, [theme.colors]);
    // Theme controls
    const setTheme = (newTheme) => {
        if (!forcedTheme) {
            setCurrentTheme(newTheme);
        }
    };
    const toggleTheme = () => {
        if (!forcedTheme) {
            setCurrentTheme((prev) => {
                if (prev === "light")
                    return "dark";
                if (prev === "dark")
                    return "system";
                return "light";
            });
        }
    };
    const value = (0, react_1.useMemo)(() => ({
        theme,
        zero,
        icons,
        isDark,
        currentTheme: forcedTheme || currentTheme,
        systemTheme: systemColorScheme || "light",
        setTheme,
        toggleTheme,
    }), [
        theme,
        zero,
        icons,
        isDark,
        forcedTheme,
        currentTheme,
        systemColorScheme,
        setTheme,
        toggleTheme,
    ]);
    const parentTheme = (0, react_1.useContext)(ThemeContext);
    const isRoot = !parentTheme;
    return ((0, jsx_runtime_1.jsx)(ThemeContext.Provider, { value: value, children: isRoot ? ((0, jsx_runtime_1.jsxs)(react_native_gesture_handler_1.GestureHandlerRootView, { children: [children, (0, jsx_runtime_1.jsx)(portal_1.PortalHost, {}), (0, jsx_runtime_1.jsx)(toast_1.ToastProvider, {})] })) : (children) }));
}
// Hook to use theme
function useTheme() {
    const context = (0, react_1.useContext)(ThemeContext);
    if (!context) {
        throw new Error("useTheme must be used within a ThemeProvider");
    }
    return context;
}
// Hook to get current platform's typography
function usePlatformTypography() {
    const { theme } = useTheme();
    return (0, react_1.useMemo)(() => {
        if (react_native_1.Platform.OS === "ios") {
            return theme.typography.ios;
        }
        else if (react_native_1.Platform.OS === "android") {
            return theme.typography.android;
        }
        return theme.typography.universal;
    }, [theme.typography]);
}
// Utility function to create theme-aware styles
function createThemedStyles(styleCreator) {
    return function useThemedStyles() {
        const { theme, zero, icons } = useTheme();
        return (0, react_1.useMemo)(() => styleCreator(theme, zero, icons), [theme, zero, icons]);
    };
}
// Create light and dark theme instances for external use
exports.lightTheme = {
    colors: createThemeColors(false),
    spacing: tokens_1.spacing,
    borderRadius: tokens_1.borderRadius,
    typography: tokens_1.typography,
    shadows: tokens_1.shadows,
    touchTargets: tokens_1.touchTargets,
    animations: tokens_1.animations,
};
exports.darkTheme = {
    colors: createThemeColors(true),
    spacing: tokens_1.spacing,
    borderRadius: tokens_1.borderRadius,
    typography: tokens_1.typography,
    shadows: tokens_1.shadows,
    touchTargets: tokens_1.touchTargets,
    animations: tokens_1.animations,
};
//# sourceMappingURL=theme.js.map