import { Namespace } from '../../utils/namespace'
import Icon from '../icon/icon.jsx'

const namespace = Namespace.Create('rate')

export default {
    name: namespace.name,
    components: {
      Icon
    },
    props: {
      value: {
        type: Number,
        default: 0
      },
      count: {
        type: Number,
        default: 5
      },
      size: {
        type: String | Number,
        default: 'middle'
      },
      gutter: {
        type: Number,
        default: 0
      },
      color: {
        type: String,
        default: '#c7c7cc'
      },
      activeColor: {
        type: String,
        default: '#FF9500'
      },
      icon: {
        type: String,
        default: 'star-line'
      },
      activeIcon: {
        type: String,
        default: 'star'
      },
      disabled: {
        type: Boolean,
        default: false
      },
      readonly: {
        type: Boolean,
        default: false
      },
      touchable: {
        type: Boolean,
        default: false
      },
      allowHalf: {
        type: Boolean,
        default: false
      }
    },
    model: {
      prop: 'value',
      event: 'change'
    },
    data() {
      return {
        rectScoreMap: []
      };
    },
    computed: {
      cls() {
        return namespace.derive({
          disabled: this.disabled
        });
      },
      itemCls() {
        return namespace.derive('item', [this.size]);
      },
      halfItemCls(){
        return namespace.derive('item-half')
      },
      iconSize() {
        if (Number.isNaN(parseInt(this.size))) {
          let res = 16;
          switch (this.size) {
            case 'small':
              res = 16;
              break;
            case 'middle':
              res = 28;
              break;
            case 'large':
              res = 32;
              break;
          }
          return res;
        } else {
          return this.size;
        }
      },
      itemMetaList() {
        const res = [];
        const value = this.value > this.count ? this.value % this.count : this.value;
        for (let i = 0; i < this.count; i++) {
          res.push(this.getMetaByIndex(i + 1, value));
        }
        return res;
      }
    },
    methods: {
      getMetaByIndex(index, value) {
        const meta = { type: this.icon, color: this.color, isHalf: false };
        if (value >= index) {
          meta.type = this.activeIcon;
          meta.color = this.activeColor;
          return meta;
        }
        if (value + 0.5 >= index && this.allowHalf) {
          meta.isHalf = true;
        }
        return meta;
      },
      mapScoreWithRange() {
        const res = [];
        for (let i = 0; i < this.itemMetaList.length; i++) {
          const rect = this.$refs[`item_${i}`].getBoundingClientRect();
          if (this.allowHalf) {
            res.push({ left: rect.left, score: i + 0.5 }, { left: rect.left + rect.width / 2, score: i + 1 });
          } else {
            res.push({ left: rect.left, score: i + 1 });
          }
        }
        this.rectScoreMap = res;
      },
      getScoreByPosition(left) {
        for (let index = this.rectScoreMap.length - 1; index > 0; index--) {
          const item = this.rectScoreMap[index];
          if (item.left <= left) {
            return item.score;
          }
        }
        return this.allowHalf ? 0.5 : 1;
      },
      onTouchStart(e) {
        if (this.readonly || !this.touchable || this.disabled) {
          return;
        }
        this.mapScoreWithRange();
      },
      onTouchMove(e) {
        if (this.readonly || !this.touchable || this.disabled) {
          return;
        }
        const { clientX } = e.touches[0];
        const score = this.getScoreByPosition(clientX);
        this.emitChange(score);
      },
      onClick(e, i) {
        if (this.readonly || this.disabled) {
          return;
        }
        let res = i;
        if (this.allowHalf) {
          const target = e.currentTarget;
          const rect = target.getBoundingClientRect();
          const left = rect.left + rect.width / 2;
          res += e.clientX <= left ? 0.5 : 1;
        } else {
          res += 1;
        }
        this.emitChange(res);
      },
      emitChange(value) {
        this.$emit('change', value);
      }
    },
    render(){
        const renderItems = ()=> this.itemMetaList.map((v,i)=>(
            <div ref={`item_${i}`} class={this.itemCls} onclick={e => this.onClick(e, i)}>
                <Icon name={v.type} color={v.color} size={this.iconSize} />
                {
                    v.isHalf &&(
                        <div class={this.halfItemCls}>
                            <Icon name={this.activeIcon} color={this.activeColor} size={this.iconSize} />
                        </div>
                    )
                }
            </div>
        ))
        return (
            <div class={this.cls} onTouchstart={this.onTouchStart} onTouchmove={this.onTouchMove}>
                {renderItems()}
            </div>
        )
    }
  };