/** @jsx createElement */

'use strict';

import { Component, createElement, PropTypes } from 'rax';
import Text from 'nuke-text';
import { isWeb } from 'nuke-env';
import Touchable from 'nuke-touchable';
import Image from 'nuke-image';
import Iconfont, { formatUnicode } from 'nuke-iconfont';
import { connectStyle } from 'nuke-theme-provider';

import stylesProvider from '../styles';

class Icon extends Component {
  constructor(props) {
    super(props);
    const { themeStyle } = props;
    this.fontURL =
      themeStyle['icon-font-path'].raw || themeStyle['icon-font-path'];
    this.fontName =
      themeStyle['icon-font-family'].raw || themeStyle['icon-font-family'];
  }
  componentDidMount() {
    const type = this.getType();
    if (type === 'iconfont') {
      let tmpFontURL = this.fontURL;
      if (this.fontURL.indexOf('.ttf') <= -1) {
        tmpFontURL += '.ttf';
      }
      Iconfont({ name: this.fontName, url: tmpFontURL });
    }
  }

  componentWillReceiveProps(nextProps) {
    const type = this.getType();
    if (type === 'iconfont') {
      const { themeStyle } = nextProps;
      const curFontUrl =
        themeStyle['icon-font-path'].raw || themeStyle['icon-font-path'];
      const curFontName =
        themeStyle['icon-font-family'].raw || themeStyle['icon-font-family'];

      if (curFontUrl !== this.fontURL || curFontName !== this.fontName) {
        this.fontURL = curFontUrl;
        this.fontName = curFontName;
        let tmpFontURL = this.fontURL;
        if (this.fontURL.indexOf('.ttf') <= -1) {
          tmpFontURL += '.ttf';
        }
        Iconfont({ name: this.fontName, url: tmpFontURL });
      }
    }
  }

  getType() {
    const { name = '' } = this.props;
    let { type = 'image' } = this.props;
    if (type === 'image' && name !== '') {
      type = 'iconfont';
    }
    return type;
  }

  render() {
    const {
      size,
      name = '',
      style,
      onPress,
      fixedFont,
      ...others
    } = this.props;
    const styles = this.props.themeStyle;

    const type = this.getType();
    if (type === 'iconfont') {
      const textStyle = Object.assign({}, styles[`iconfont-${size}`], style, {
        fontFamily: this.fontName,
      });
      const unicode =
        styles[`icon-content-${name}`] &&
        formatUnicode(styles[`icon-content-${name}`], 16);
      return (
        <Text
          onClick={onPress}
          {...others}
          fixedFont={fixedFont}
          style={textStyle}
        >
          {unicode}
        </Text>
      );
    }
    const wrapStyle = Object.assign({}, styles['icon-image'], style);
    const sizeStyle = styles[`image-${size}`];
    return (
      <Touchable onPress={onPress} style={wrapStyle} {...others}>
        <Image
          source={{ uri: this.props.src }}
          style={sizeStyle}
          resizeMode={'cover'}
        />
      </Touchable>
    );
  }
}

Icon.displayName = 'Icon';

Icon.defaultProps = {
  size: 'medium',
  style: {},
  name: '',
  onPress: () => {},
  src: '',
  type: 'image',
  fixedFont: false,
};
Icon.propTypes = {
  onPress: PropTypes.func,
  name: PropTypes.any,
  themeStyle: PropTypes.any,
  style: PropTypes.any,
  src: PropTypes.string,
  type: PropTypes.string,
  size: PropTypes.oneOf(['xs', 'small', 'medium', 'large']),
  fixedFont: PropTypes.boolean,
};

Icon.contextTypes = {
  parentPath: PropTypes.any,
  parentStyle: PropTypes.any,
};
const StyledIcon = connectStyle(stylesProvider)(Icon);

export default StyledIcon;
