import Model from './Model';
import { enableClassManagement, merge, clone, isString, isObject, map, isArray, each } from '../util';
import dirtyActions from '../action/dirty';
import globalDefault from './globalDefault';

const TYPE = 'component';

/**
 * 组件Model类
 * 
 * @class ComponentModel
 * @extends {Model}
 */
class ComponentModel extends Model {

    /**
     * {string} 组件名type
     */
    static type = TYPE;

    /**
     * {Array<string>} 支持emphasis配置的选项数组,兼容emphasis另一种写法
     */
    static emphasisList = undefined;

    __dataDirty = true;

    constructor(option, parentModel, globalModel, global, attr) {
        super(...arguments);
        for (let a in attr) {
            this[a] = attr[a];
        }
        
        // 对option进行clone
        let data = option.data;
        let originData = option.originData;

        delete option.data;
        delete option.originData;
        this.option = clone(this.option);
        data !== undefined && (option.data = this.option.data = data);
        originData !== undefined && (option.originData = this.option.originData = originData);
        
        this.formatOption(this.option);
        this._option = merge(this.option, this.constructor.defaultOption, false);

        // this.formatOption(this.option);
        // this._option = merge(clone(this.constructor.defaultOption), this.option, true);
    }

    /**
     * 兼容emphasis另一种写法
     * @param {Object} option 
     * @private
     */
    formatOption(option) {
        let emphasisList = this.constructor.emphasisList;
        let emphasis = option.emphasis || {};

        if (emphasisList) {
            each(emphasisList, function (key) {
                let target = option[key];

                if (!target) {
                    emphasis[key] && (option[key] = {
                        emphasis: emphasis[key]
                    });
                } else if (!target.normal && !target.emphasis) {
                    if (target.style && (target.style.normal || target.style.emphasis)) { // 兼容旧的配置方法
                        target.style.normal && (option[key] = {
                            normal: {
                                ...target,
                                style: target.style.normal
                            }
                        });
                        target.style.emphasis && (option[key].emphasis = {
                                ...target,
                                style: target.style.emphasis
                            }
                        );
                    } else {
                        option[key] = {
                            normal: target
                        };
                        emphasis[key] && (option[key].emphasis = emphasis[key]);
                    }
                }
            });
        }
    }

    /**
     * 根据$axisIndex获取axisModel
     * 
     * @param {string} xOrY 'x'或'y'
     * @returns {Object} axisModel
     */
    getAxisModel(xOrY) {
        let { globalModel } = this;
        let axisModel;

        each(this.get('$axisIndex'), (index) => {
            let axis = globalModel.getComponentByIndex('axis', index);

            if (axis.get('xOrY') === xOrY) {
                axisModel = axis;
            }
        });

        return axisModel;
    }

    /**
     * 通过$dataIndex更新数据
     */
    updateData() {
        let data = this.get('data');
        let dataIndex = this.get('$dataIndex');
        let needDirty = true;

        if (typeof dataIndex !== 'undefined') {
            let dataModel = this.globalModel.getComponentByIndex('data', dataIndex);
            let dataKey = this.get('dataKey');
            let data = dataModel.getData(dataKey);

            if (data) {
                this._data = data;
            } else {
                needDirty = false;
            }

        } else if (data !== undefined) { // TODO 兼容data配置参数代码,之后用 $dataIndex代替
            let dataIndex = data.dataIndex;

            if (typeof dataIndex === 'undefined') {
                this._data = data;
            } else {
                let dataModel = this.globalModel.getComponentByIndex('data', data.dataIndex);

                this._data = dataModel.getData(data.key);
            }
        } else {
            needDirty = false;
        }

        if (needDirty) {
            this.formatData && (this._data = this.formatData(this._data));

            this.__dataDirty = false;
            // console.log(`${this.type}_${this.index}更新了数据!`);
            // TODO 不同类型属性更新,UPDATEDATA、POPDATA等
            this.dirty({
                type: dirtyActions.dataUpdate,
                payload: {}
            });
        }
    }

    /**
     * 获取计算后的数据
     * 
     * @param {string} [key] 返回内部data 
     * @returns {any} 返回数据
     */
    getData(key) {
        if (this._data !== undefined) {
            return typeof key === 'undefined' ? this._data : this._data[key];
        }
    }

    /**
     * 触发dataDirty的事件
     * 
     * @param {Object} action 
     * @returns boolean true
     */
    dataDirty(action) {
        this.__dataDirty = true;

        return true;
    }

    /**
     * 是否为dataDirty
     * 
     * @returns {boolean} 是否为dataDirty
     */
    isDataDirty() {
        return this.__dataDirty;
    }

    /**
     * 获取实际option
     * 
     * @param {string} [key] 获取option内的key属性,若不传返回全部option
     * @returns {any} 返回key对应的属性
     */
    get(key) {
        if (key) {
            if (globalDefault[key] !== undefined && this.option[key] === undefined) {
                let globalModel = this.globalModel;

                return globalModel.get(key);
            } else {
                return this._option[key];
            }
        } else {
            return this._option;
        }
    }

    set(key, value) {
        if (key === 'data') {
            this.dataDirty();
        }
        
        super.set(key, value);
    }
};

export default enableClassManagement(ComponentModel);