import React, { forwardRef, } from 'react';
import { Platform, StyleSheet, } from 'react-native';
import { useBreakpoint, useViewportUnits } from './hooks';
const webStyles = [
    'cursor',
    'touchAction',
    'userSelect',
    'willChange',
    'outlineColor',
    'outlineOffset',
    'outlineStyle',
    'outlineWidth',
    'transitionDelay',
    'transitionDuration',
    'transitionProperty',
    'transitionTimingFunction',
];
const borderRadiusStyles = [
    'borderBottomLeftRadius',
    'borderBottomRightRadius',
    'borderRadius',
    'borderTopLeftRadius',
    'borderTopRightRadius',
];
const colorStyles = ['backfaceVisibility', 'backgroundColor', 'borderColor', 'opacity'];
const shadowStyles = [
    'shadowColor',
    'shadowOffset',
    'shadowOpacity',
    'shadowRadius',
];
const transformsStyles = ['transform'];
const layoutStyles = [
    'alignContent',
    'alignItems',
    'alignSelf',
    'aspectRatio',
    'borderBottomWidth',
    'borderEndWidth',
    'borderLeftWidth',
    'borderRightWidth',
    'borderStartWidth',
    'borderTopWidth',
    'borderWidth',
    'bottom',
    'direction',
    'display',
    'end',
    'flex',
    'flexBasis',
    'flexDirection',
    'flexGrow',
    'flexShrink',
    'flexWrap',
    'height',
    'justifyContent',
    'left',
    'margin',
    'marginBottom',
    'marginEnd',
    'marginHorizontal',
    'marginLeft',
    'marginRight',
    'marginStart',
    'marginTop',
    'marginVertical',
    'maxHeight',
    'maxWidth',
    'minHeight',
    'minWidth',
    'overflow',
    'padding',
    'paddingBottom',
    'paddingEnd',
    'paddingHorizontal',
    'paddingLeft',
    'paddingRight',
    'paddingStart',
    'paddingTop',
    'paddingVertical',
    'position',
    'right',
    'start',
    'top',
    'width',
    'zIndex',
];
export const viewStyles = [
    'borderBottomColor',
    'borderBottomEndRadius',
    'borderBottomStartRadius',
    'borderEndColor',
    'borderLeftColor',
    'borderRightColor',
    'borderStartColor',
    'borderStyle',
    'borderTopColor',
    'borderTopEndRadius',
    'borderTopStartRadius',
    'elevation',
    ...colorStyles,
    ...borderRadiusStyles,
    ...layoutStyles,
    ...shadowStyles,
    ...transformsStyles,
    ...webStyles,
];
export const textStyles = [
    'color',
    'fontFamily',
    'fontSize',
    'fontStyle',
    'fontWeight',
    'includeFontPadding',
    'fontVariant',
    'letterSpacing',
    'lineHeight',
    'textAlign',
    'textAlignVertical',
    'textDecorationColor',
    'textDecorationLine',
    'textDecorationStyle',
    'textShadowColor',
    'textShadowOffset',
    'textShadowRadius',
    'textTransform',
    'writingDirection',
    ...viewStyles,
];
export const imageStyles = [
    'overlayColor',
    'resizeMode',
    'tintColor',
    ...borderRadiusStyles,
    ...layoutStyles,
    ...shadowStyles,
    ...transformsStyles,
    ...webStyles,
];
export const capitalize = (str) => `${str.charAt(0).toUpperCase()}${str.slice(1)}`;
export const uncapitalize = (str) => `${str.charAt(0).toLowerCase()}${str.slice(1)}`;
export const prefixStyles = (styles, prefix) => styles.map((style) => `${uncapitalize(prefix)}${capitalize(style)}`);
export const unPrefixStyle = (style, prefix) => uncapitalize(style.slice(prefix.length));
export const responsiveValue = (prop, value) => {
    if (prop === 'transform') {
        if (Array.isArray(value) && Array.isArray(value[0])) {
            return value;
        }
        return [value];
    }
    if (Array.isArray(value)) {
        return value;
    }
    return [value];
};
export const breakpointValue = (prop, value) => {
    return responsiveValue(prop, value)
        .slice(0, useBreakpoint() + 1)
        .pop();
};
export const normalizeValue = (prop, value) => {
    const val = breakpointValue(prop, value);
    if (Platform.OS === 'web') {
        return val;
    }
    if (typeof val !== 'string') {
        return val;
    }
    const match = val.match(/^([+-]?\d*\.?\d+)(vw|vh|vmin|vmax)$/);
    if (!match) {
        return val;
    }
    return (parseFloat(match[1]) *
        useViewportUnits()[match[2]]);
};
export const createStyleSheet = StyleSheet.create;
const StyleStyles = {
    view: viewStyles,
    text: textStyles,
    image: imageStyles,
};
export const styled = (Component, styles) => {
    const StyledComponent = forwardRef((props, ref) => {
        const allStyles = {};
        const attrs = {};
        const prefixes = Object.keys(styles);
        const prefixedStyles = prefixes.reduce((prefixedStyles, prefix) => (Object.assign(Object.assign({}, prefixedStyles), {
            [prefix]: prefix === 'style'
                ? StyleStyles[styles[prefix]]
                : prefixStyles(StyleStyles[styles[prefix]], prefix.replace(/style$/i, '')),
        })), {});
        Object.entries(props).forEach(([prop, value]) => {
            const prefix = prefixes.find((prefix) => prefixedStyles[prefix].includes(prop));
            if (prefix !== undefined) {
                const styleProp = prefix === 'style'
                    ? prop
                    : unPrefixStyle(prop, prefix.replace(/style$/i, ''));
                allStyles[prefix] = Object.assign(Object.assign({}, (allStyles[prefix] || {})), {
                    [styleProp]: normalizeValue(styleProp, value),
                });
            }
            else {
                attrs[prop] = value;
            }
        });
        return (<Component {...attrs} ref={ref} {...Object.entries(createStyleSheet(allStyles)).reduce((res, [key, value]) => (Object.assign(Object.assign({}, res), {
            [key]: [
                value,
                attrs[key],
            ],
        })), {})}/>);
    });
    StyledComponent.displayName = Component.displayName;
    return StyledComponent;
};
//# sourceMappingURL=styled.jsx.map