"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TextPrimitive = exports.TextBlock = exports.TextSpan = exports.TextRoot = exports.TextContext = void 0;
exports.objectFromObjects = objectFromObjects;
exports.useTextContext = useTextContext;
exports.createTextStyle = createTextStyle;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const react_native_1 = require("react-native");
const theme_1 = require("../../../lib/theme/theme");
const tokens_1 = require("../../../lib/theme/tokens");
exports.TextContext = (0, react_1.createContext)(null);
function objectFromObjects(arr) {
    return Object.assign({}, ...arr);
}
// Size mapping
const sizeMap = {
    xs: 12,
    sm: 14,
    base: 16,
    lg: 18,
    xl: 20,
    "2xl": 24,
    "3xl": 30,
    "4xl": 36,
};
// Size-specific line height mapping (provides better default line heights for each size)
const sizeLineHeightMap = {
    xs: 16, // 12px * 1.33 = tight but readable
    sm: 20, // 14px * 1.43 = good for small text
    base: 24, // 16px * 1.5 = standard body text
    lg: 28, // 18px * 1.56 = comfortable for larger text
    xl: 30, // 20px * 1.5 = balanced
    "2xl": 32, // 24px * 1.33 = tighter for headings
    "3xl": 36, // 30px * 1.2 = tight for large headings
    "4xl": 40, // 36px * 1.11 = very tight for display text
};
// Weight mapping
const weightMap = {
    thin: "100",
    light: "300",
    normal: "400",
    medium: "500",
    semibold: "600",
    bold: "700",
    extrabold: "800",
    black: "900",
};
// Line height mapping
const leadingMap = {
    none: 1,
    tight: 1.2,
    snug: 1.3,
    normal: 1.5,
    relaxed: 1.7,
    loose: 2,
};
// Letter spacing mapping
const trackingMap = {
    tighter: -0.8,
    tight: -0.4,
    normal: 0,
    wide: 0.4,
    wider: 0.8,
    widest: 1.6,
};
// Variant definitions (platform-aware)
const getVariantStyles = () => {
    // get platform-specific typography
    // iOS, Android, Web (Universal)
    const typographicPlatform = (react_native_1.Platform.OS === "ios"
        ? "ios"
        : react_native_1.Platform.OS === "android"
            ? "android"
            : "universal");
    const platformTypography = tokens_1.typography[typographicPlatform];
    if (!platformTypography) {
        throw new Error("Platform typography not defined");
    }
    // Define mapping based on platform
    if (typographicPlatform === "ios") {
        return {
            h1: platformTypography.largeTitle,
            h2: platformTypography.title1,
            h3: platformTypography.title2,
            h4: platformTypography.title3,
            h5: platformTypography.headline,
            h6: platformTypography.headline,
            subtitle1: platformTypography.subhead,
            subtitle2: platformTypography.footnote,
            body1: platformTypography.body,
            body2: platformTypography.callout,
            caption: platformTypography.caption1,
            overline: platformTypography.caption2,
        };
    }
    else if (typographicPlatform === "android") {
        return {
            h1: platformTypography.headline4, // 34px instead of 96px
            h2: platformTypography.headline5, // 24px instead of 60px
            h3: platformTypography.headline6, // 20px instead of 48px
            h4: platformTypography.subtitle1, // 16px instead of 34px
            h5: platformTypography.subtitle2, // 14px instead of 24px
            h6: platformTypography.subtitle2, // 14px - consistent with h5
            subtitle1: platformTypography.subtitle1,
            subtitle2: platformTypography.subtitle2,
            body1: platformTypography.body1,
            body2: platformTypography.body2,
            caption: platformTypography.caption,
            overline: platformTypography.overline,
        };
    }
    else {
        // universal
        // Map variants to universal sizes
        return {
            h1: platformTypography["4xl"],
            h2: platformTypography["3xl"],
            h3: platformTypography["2xl"],
            h4: platformTypography["xl"],
            h5: platformTypography["lg"],
            h6: platformTypography["base"],
            subtitle1: platformTypography.base,
            subtitle2: platformTypography.sm,
            body1: platformTypography.base,
            body2: platformTypography.sm,
            caption: platformTypography.xs,
            overline: platformTypography.xs,
        };
    }
};
// Text root primitive
exports.TextRoot = (0, react_1.forwardRef)(({ variant, size, weight, color, align, leading, tracking, transform, decoration, italic = false, opacity, style, inherit = true, reset = false, children, ...props }, ref) => {
    const { theme } = (0, theme_1.useTheme)();
    const parentContext = (0, react_1.useContext)(exports.TextContext);
    // Get variant styles
    const variantStyles = getVariantStyles();
    // Calculate inherited values
    const inheritedContext = inherit && !reset && parentContext ? parentContext : {};
    // Calculate fontSize first for line height calculation
    let calculatedFontSize = inheritedContext.fontSize;
    // Apply variant font size
    if (variant && variantStyles[variant]?.fontSize) {
        calculatedFontSize = variantStyles[variant].fontSize;
    }
    // Apply size-based font size
    if (size) {
        calculatedFontSize = typeof size === "number" ? size : sizeMap[size];
    }
    // Use default if still undefined
    calculatedFontSize = calculatedFontSize || 16;
    // Calculate final styles
    const finalStyles = {
        // Start with inherited values
        fontSize: inheritedContext.fontSize,
        fontWeight: inheritedContext.fontWeight,
        //color: inheritedContext.color,
        fontFamily: inheritedContext.fontFamily,
        lineHeight: inheritedContext.lineHeight,
        textAlign: inheritedContext.textAlign,
        letterSpacing: inheritedContext.letterSpacing,
        textTransform: inheritedContext.textTransform,
        textDecorationLine: inheritedContext.textDecorationLine,
        fontStyle: inheritedContext.fontStyle,
        opacity: inheritedContext.opacity,
        // Apply variant styles (these may override inherited)
        ...(variant && variantStyles[variant]),
        // Apply explicit prop styles (these should override inherited and variant)
        // Apply size (with corresponding line height if not explicitly set)
        ...(size && {
            fontSize: typeof size === "number" ? size : sizeMap[size],
            // Apply size-specific line height only if leading is not explicitly set
            ...(leading === undefined && {
                lineHeight: typeof size === "number"
                    ? size // Auto line height for numeric sizes
                    : sizeLineHeightMap[size],
            }),
        }),
        // Apply weight
        ...(weight && {
            fontWeight: weightMap[weight],
        }),
        // Apply color
        ...(color
            ? {
                color: color === "default"
                    ? theme.colors.text
                    : color === "muted"
                        ? theme.colors.textMuted
                        : color === "primary"
                            ? theme.colors.primary
                            : color === "secondary"
                                ? theme.colors.secondary
                                : color === "destructive"
                                    ? theme.colors.destructive
                                    : color === "success"
                                        ? theme.colors.success
                                        : color === "warning"
                                            ? theme.colors.warning
                                            : color || inheritedContext.color, // Custom color string
            }
            : { color: inheritedContext.color || theme.colors.text }),
        // Apply alignment
        ...(align && {
            textAlign: align,
        }),
        // Apply line height
        ...(leading && {
            lineHeight: typeof leading === "number"
                ? leading
                : leadingMap[leading] * calculatedFontSize,
        }),
        // Apply letter spacing
        ...(tracking && {
            letterSpacing: typeof tracking === "number" ? tracking : trackingMap[tracking],
        }),
        // Apply text transform
        ...(transform &&
            transform !== "none" && {
            textTransform: transform,
        }),
        // Apply text decoration
        ...(decoration &&
            decoration !== "none" && {
            textDecorationLine: decoration,
        }),
        // Apply italic
        ...(italic && {
            fontStyle: "italic",
        }),
        // Apply opacity
        ...(opacity !== undefined && {
            opacity,
        }),
    };
    finalStyles.color = finalStyles.color;
    // Create context value for children
    // Process custom styles to auto-add line height for fontSize
    const processedStyle = Array.isArray(style)
        ? style
        : [style].filter(Boolean);
    const enhancedStyles = processedStyle.map((styleObj) => {
        if (styleObj && typeof styleObj === "object" && "fontSize" in styleObj) {
            const fontSize = styleObj.fontSize;
            if (typeof fontSize === "number" && !styleObj.lineHeight && !leading) {
                return {
                    ...styleObj,
                    lineHeight: fontSize,
                };
            }
        }
        return styleObj;
    });
    const contextValue = {
        fontSize: typeof finalStyles.fontSize === "number"
            ? finalStyles.fontSize
            : undefined,
        fontWeight: finalStyles.fontWeight,
        color: finalStyles.color || undefined,
        fontFamily: typeof finalStyles.fontFamily === "string"
            ? finalStyles.fontFamily
            : undefined,
        lineHeight: typeof finalStyles.lineHeight === "number"
            ? finalStyles.lineHeight
            : undefined,
        textAlign: finalStyles.textAlign,
        letterSpacing: finalStyles.letterSpacing,
        textTransform: finalStyles.textTransform,
        textDecorationLine: finalStyles.textDecorationLine,
        fontStyle: finalStyles.fontStyle,
        opacity: finalStyles.opacity,
    };
    return ((0, jsx_runtime_1.jsx)(exports.TextContext.Provider, { value: contextValue, children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { ref: ref, style: [finalStyles, ...enhancedStyles], ...props, children: children }) }));
});
exports.TextRoot.displayName = "TextRoot";
// Text span primitive (inherits from parent but doesn't create new context)
exports.TextSpan = (0, react_1.forwardRef)(({ children, ...props }, ref) => {
    return ((0, jsx_runtime_1.jsx)(exports.TextRoot, { ref: ref, inherit: true, ...props, children: children }));
});
exports.TextSpan.displayName = "TextSpan";
// Text block primitive (always creates new context)
exports.TextBlock = (0, react_1.forwardRef)(({ children, reset = true, ...props }, ref) => {
    return ((0, jsx_runtime_1.jsx)(exports.TextRoot, { ref: ref, reset: reset, ...props, children: children }));
});
exports.TextBlock.displayName = "TextBlock";
// Hook to access current text context
function useTextContext() {
    return (0, react_1.useContext)(exports.TextContext);
}
// Utility function to create text styles
function createTextStyle(props) {
    // This is a utility function that can be used to generate styles
    // without rendering a component
    const style = {};
    if (props.size) {
        style.fontSize =
            typeof props.size === "number" ? props.size : sizeMap[props.size];
        // Apply size-specific line height only if leading is not explicitly set
        if (props.leading === undefined) {
            style.lineHeight =
                typeof props.size === "number"
                    ? props.size
                    : sizeLineHeightMap[props.size];
        }
    }
    if (props.weight) {
        style.fontWeight = weightMap[props.weight];
    }
    if (props.align) {
        style.textAlign = props.align;
    }
    if (props.leading) {
        const fontSize = style.fontSize || 16; // default font size
        style.lineHeight =
            typeof props.leading === "number"
                ? props.leading
                : leadingMap[props.leading] * fontSize;
    }
    if (props.tracking) {
        style.letterSpacing =
            typeof props.tracking === "number"
                ? props.tracking
                : trackingMap[props.tracking];
    }
    if (props.transform && props.transform !== "none") {
        style.textTransform = props.transform;
    }
    if (props.decoration && props.decoration !== "none") {
        style.textDecorationLine = props.decoration;
    }
    if (props.italic) {
        style.fontStyle = "italic";
    }
    if (props.opacity !== undefined) {
        style.opacity = props.opacity;
    }
    return style;
}
// Export primitive collection
exports.TextPrimitive = {
    Root: exports.TextRoot,
    Span: exports.TextSpan,
    Block: exports.TextBlock,
    Context: exports.TextContext,
    useContext: useTextContext,
    createStyle: createTextStyle,
};
//# sourceMappingURL=text.js.map