import { forEach, map, get as lodashGet, merge } from 'lodash'; // import type { ColorMode } from './color-mode';

import { isEmptyObj } from '../utils/isEmptyObj';
import { theme } from '../theme';
import { updateComponentThemeMap } from '../utils/styled'; // Adding Map for storing the props and style for the styled component

export let resolvedStyledMap = {};
export const pseudoPropStateMap = {
  _disabled: 'isDisabled',
  _focusVisible: 'isFocusVisible',
  _focus: 'isFocused',
  _hover: 'isHovered',
  _pressed: 'isPressed',
  _checked: 'isChecked',
  _loading: 'isLoading',
  _invalid: 'isInvalid',
  _reversed: 'isReversed'
};
export const PSEUDO_PROP_COMPONENT_MAP = {
  _spinner: 'Spinner',
  _stack: 'Stack',
  _text: 'Text',
  _icon: 'Icon',
  _checkbox: 'Checkbox',
  _radio: 'Radio',
  _pressable: 'Pressable' // _label: 'Text',
  // _input: 'Input',
  // _slide: 'Slide',
  // _backdropFade: 'BackdropFade',
  // _fade: 'Fade',

};
export const COLOR_SCHEME_MAP = {
  Button: true,
  ButtonGroup: true,
  IconButton: true,
  Checkbox: true,
  Radio: true,
  Alert: true,
  Badge: true,
  CircularProgress: true,
  Fab: true,
  Modal: true,
  Progress: true,
  Switch: true,
  Tag: true,
  Slider: true,
  SliderThumb: true,
  // SliderTrack: true,
  SliderFilledTrack: true
};
export const init = inputResolvedStyledMap => {
  // resolvedStyledMap = new Map();
  if (inputResolvedStyledMap) {
    resolvedStyledMap = inputResolvedStyledMap;
  }

  if (process.env.NODE_ENV === 'development') {
    //@ts-ignore
    window['resolvedStyledMap'] = resolvedStyledMap; //@ts-ignore
  }
};
export const get = key => {
  // console.log(key, 'key here 111');
  // console.log(resolvedStyledMap[key], 'key here 111');
  return resolvedStyledMap[key];
};
export const getThemeObject = (componentName, colorMode, state) => {
  const styleObj = resolvedStyledMap[componentName];

  if (!styleObj) {
    return {};
  } // Theme style


  let styleSheet = styleObj[colorMode]; // state style

  const stateStyles = getPseudoStateStyles(componentName, state);
  forEach(stateStyles, stateStyleObj => {
    if (stateStyleObj[colorMode]) {
      styleSheet = styleSheet.concat(stateStyleObj[colorMode]);
    }
  });
  const unResolvedPropsArray = map(styleSheet, 'unResolvedProps');
  let unResolvedProps = {};

  for (const props of unResolvedPropsArray) {
    unResolvedProps = { ...unResolvedProps,
      ...props
    };
  }

  const restDefaultPropsArray = map(styleSheet, 'restDefaultProps');
  let restDefaultProps = {};

  for (const props of restDefaultPropsArray) {
    restDefaultProps = { ...restDefaultProps,
      ...props
    };
  }

  const styleFromPropsArray = map(styleSheet, 'styleFromProps');
  let styleFromProps = {};

  for (const props of styleFromPropsArray) {
    styleFromProps = { ...styleFromProps,
      ...props
    };
  }

  const internalPseudoPropsArray = map(styleSheet, 'internalPseudoProps');
  let internalPseudoProps = {};

  for (const props of internalPseudoPropsArray) {
    internalPseudoProps = { ...internalPseudoProps,
      ...props
    };
  }

  return {
    style: map(styleSheet, 'style'),
    unResolvedProps: unResolvedProps,
    styleFromProps: styleFromProps,
    restDefaultProps: restDefaultProps,
    internalPseudoProps: internalPseudoProps
  };
};

const getComponentNameKeyFromProps = (componentName, {
  variant,
  colorScheme
} = {}) => {
  var _componentTheme$defau;

  let componentKeyName = componentName;
  const componentTheme = lodashGet(theme, "components.".concat(componentName), {});
  const colorSchemeKey = colorScheme || ((_componentTheme$defau = componentTheme.defaultProps) === null || _componentTheme$defau === void 0 ? void 0 : _componentTheme$defau.colorScheme);

  if (colorSchemeKey && variant) {
    componentKeyName = "".concat(componentName, ".").concat(colorSchemeKey, ".").concat(variant);
  } else if (variant) {
    componentKeyName = "".concat(componentName, ".").concat(variant);
  } else if (colorSchemeKey) {
    componentKeyName = "".concat(componentName, ".").concat(colorSchemeKey);
  }

  return componentKeyName;
}; // const get


export const getThemeProps = (inputComponentKeyName, config, state, props = {}) => {
  const componentNames = inputComponentKeyName.split('.');
  const rootComponentName = componentNames[0];
  const pseudoComponentKeyName = componentNames[1];
  let componentKeyName = rootComponentName;
  componentKeyName = getComponentNameKeyFromProps(rootComponentName, props);

  if (pseudoComponentKeyName) {
    componentKeyName = "".concat(componentKeyName, ".").concat(pseudoComponentKeyName);
  }

  let themeObj = getThemeObject(componentKeyName, config.colorMode, state);

  if (isEmptyObj(themeObj)) {
    updateComponentThemeMap(inputComponentKeyName, {}, config, true, props);
    themeObj = getThemeObject(componentKeyName, config.colorMode, state);
  }

  if (!isEmptyObj(themeObj) && props.size) {
    var _sizeThemeObj, _themeObj, _sizeThemeObj2;

    let componentKeyNameForSize = "".concat(rootComponentName, ".").concat(props.size);

    if (pseudoComponentKeyName) {
      componentKeyNameForSize = "".concat(componentKeyNameForSize, ".").concat(pseudoComponentKeyName);
    }

    let sizeThemeObj = getThemeObject("".concat(componentKeyNameForSize), config.colorMode, state);

    if (isEmptyObj(sizeThemeObj)) {
      updateComponentThemeMap(rootComponentName, {}, config, true, props);
      sizeThemeObj = getThemeObject(componentKeyNameForSize, config.colorMode, state);
    }

    const mergedThemeObj = {
      style: (_sizeThemeObj = sizeThemeObj) !== null && _sizeThemeObj !== void 0 && _sizeThemeObj.style ? [...((_themeObj = themeObj) === null || _themeObj === void 0 ? void 0 : _themeObj.style), ...((_sizeThemeObj2 = sizeThemeObj) === null || _sizeThemeObj2 === void 0 ? void 0 : _sizeThemeObj2.style)] : themeObj.style,
      styleFromProps: merge({}, themeObj.styleFromProps, sizeThemeObj.styleFromProps),
      unResolvedProps: merge({}, themeObj.unResolvedProps, sizeThemeObj.unResolvedProps),
      internalPseudoProps: merge({}, themeObj.internalPseudoProps, sizeThemeObj.internalPseudoProps),
      restDefaultProps: { ...themeObj.restDefaultProps,
        ...sizeThemeObj.restDefaultProps
      }
    };
    themeObj = mergedThemeObj;
  }

  return themeObj;
};
export const getResolvedProps = (key, colorMode) => {
  const styleObj = resolvedStyledMap[key];

  if (!colorMode || !styleObj) {
    return null;
  }

  return styleObj[colorMode]['styleFromProps'];
};

const isValidStateKey = (stateKey, state) => {
  // console.log(stateKey, pseudoPropStateMap[stateKey], state, 'is valid');
  try {
    //@ts-ignore
    return state[pseudoPropStateMap[stateKey]];
  } catch (e) {
    return false;
  }
};

const isValidState = (key, state) => {
  // include only startWith("_")
  const stateKeys = key.split('.');
  const isValid = stateKeys.every(stateKey => {
    if (isValidStateKey(stateKey, state)) {
      return true;
    }

    return false;
  }); // console.log(isValid, 'valid here');

  return isValid;
};

const getPseudoStateStyles = (componentName, state) => {
  const styleObj = [];
  const stateStyleArray = [];
  const componentStates = get(componentName); // console.log(componentStates, '***** &&&&');

  for (const k in componentStates) {
    const value = componentStates[k]; // console.log(componentStates, k, componentName, 'value **&');
    //get for _hover, _checked

    if (k.startsWith('_')) {
      // const pseudoPropKey = k.slice(componentName.length + 1);
      stateStyleArray.push({
        key: k,
        value: value
      });
    }
  } // sort for specificity


  stateStyleArray.sort((obj1, obj2) => obj1.key.length - obj2.key.length);
  stateStyleArray.forEach(item => {
    if (isValidState(item.key, state)) {
      styleObj.push(item.value);
    }
  }); // console.log(styleObj, 'valid state *');

  return styleObj;
}; // export const getResolvedStyleSheet = (
//   componentName: string | Array<any>,
//   colorMode?: ColorMode,
//   state?: any,
//   variant?: any,
//   size?: any
// ) => {
//   if (typeof componentName !== 'string') {
//     componentName = componentName.filter((item) => item).join('.');
//     // console.log(componentName, 'component name &&&^');
//   } else {
//     if (variant && size) {
//       componentName = `${componentName}.${variant}.${size}`;
//     } else if (variant) {
//       componentName = `${componentName}.${variant}`;
//     } else if (size) {
//       componentName = `${componentName}.${size}`;
//     }
//   }
//   const styleObj: any = resolvedStyledMap.get(componentName);
//   // console.log(componentName, colorMode, styleObj, 'component name &&&&&');
//   if (!colorMode || !styleObj) {
//     return null;
//   }
//   // Theme style
//   const styleSheet = map(styleObj[colorMode], 'style');
//   // state style
//   const stateStyles = getPseudoStateStyles(componentName, state);
//   forEach(stateStyles, (stateStyleObj) => {
//     // console.log(
//     //   componentName,
//     //   stateStyleObj[colorMode].style,
//     //   map(stateStyleObj[colorMode], 'style'),
//     //   'hello component name )))'
//     // );
//     styleSheet.push(map(stateStyleObj[colorMode], 'style'));
//   });
//   return styleSheet;
// };


export const set = (key, value, colorMode) => {
  const styledMap = resolvedStyledMap[key];

  if (!styledMap) {
    resolvedStyledMap[key] = {
      [colorMode]: [value]
    };
  } else {
    if (!styledMap[colorMode]) {
      styledMap[colorMode] = [];
    }

    styledMap[colorMode].push(value);
  }
};
export const log = () => {// console.log(resolvedStyledMap);
};
//# sourceMappingURL=ResolvedStyleMap.js.map