import { ThemeStyles, ThemeTokens } from '../styles/defaults/themes.interface';
import { Style } from './Style';
import { Token } from './Token';
import { getLookupTableForThisApp } from './Theme';
import { StyleUtils } from '../utils/style.utils';
import { THEMES } from './presets';
import { htmlTags } from './style.interface';
import { TOKEN_KEY_SEPARATOR, TokenType } from './token.interface';

export interface BaseThemeSettings {
  tokens: Record<string, Token>;
  styles: Record<string, Style>;
}

/**
 * Get theme settings for this app
 * @param theme
 * @returns
 */
export const getDefaultThemeSettings = (
  theme: 'dark' | 'light'
): BaseThemeSettings => {
  let tokens = THEMES.APPHOUSE_DARK.tokens;
  if (theme === 'light') {
    tokens = THEMES.APPHOUSE_LIGHT.tokens;
  }
  return {
    tokens: tokenize(tokens),
    styles: parsetheme(theme)
  };
};

/**
 * Convert object to Record<string, Token>
 * @param tokens ThemeTokens tokens in object format
 * @returns Record<string, Token>
 */
export const tokenize = (tokens: ThemeTokens): Record<string, Token> => {
  const hashedTokens: Record<string, Token> = {};

  const getTokens = (dTokens: ThemeTokens) => {
    Object.keys(dTokens).forEach((type: string) => {
      //@ts-ignore
      const tKeys = dTokens[type];
      Object.keys(tKeys).forEach((key: string) => {
        const hashedTokenId = `${type}${TOKEN_KEY_SEPARATOR}${key}`;
        const tokn: TokenType = {
          key,
          value: tKeys[key],
          type
        };

        hashedTokens[hashedTokenId] = new Token(tokn);
      });
    });
  };
  getTokens(tokens);
  return hashedTokens;
};

const getPreviewWithTagFromKey = (key: string) => {
  if (key.indexOf('custom') >= 0) {
    return 'SearchInput';
  }
  if (key.indexOf('button') >= 0) {
    return 'button';
  }

  if (key.indexOf('input') >= 0) {
    return 'input';
  }

  if (key.indexOf('layout') >= 0) {
    return 'div';
  }

  if (['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p'].includes(key)) {
    return 'p';
  }

  if (key.indexOf('typography') >= 0) {
    return 'p';
  }
  if (key.indexOf('text') >= 0) {
    return 'p';
  }

  if (key.indexOf('label') >= 0) {
    return 'label';
  }
  if (htmlTags.find((tag) => tag.indexOf(key) >= 0)) {
    return key;
  } else {
    return 'div';
  }
};

/**
 * Parse styles of this app
 * @param theme
 * @returns
 */
export const parsetheme = (theme: 'dark' | 'light'): Record<string, Style> => {
  const hashedStyles: Record<string, Style> = {};

  const getStyles = (styles: ThemeStyles) => {
    styles &&
      Object.keys(styles).forEach((key) => {
        //@ts-ignore
        const s = styles[key];
        Object.keys(s).forEach((p) => {
          const hashedStyleId = `${key}.${p}`;
          let previewWithTag = getPreviewWithTagFromKey(key);

          if (key === 'button' && p === 'select') {
            previewWithTag = 'select';
          }
          if (key === 'input' && p === 'label') {
            previewWithTag = 'label';
          }

          const namespace = `${key}${TOKEN_KEY_SEPARATOR}${p}`;
          const value = StyleUtils.toCssPropertyStyle(
            s[p],
            getLookupTableForThisApp(),
            namespace
          );

          const style = {
            id: hashedStyleId,
            value,
            baseComponent: key,
            variant: p,
            state: 'active',
            previewWithTag
          };
          hashedStyles[hashedStyleId] = new Style(style);
        });
      });
  };

  if (theme === 'light') {
    getStyles(THEMES.APPHOUSE_LIGHT.styles);
  }

  if (theme === 'dark') {
    getStyles(THEMES.APPHOUSE_DARK.styles);
  }

  return hashedStyles;
};
