import { __decorate } from "tslib";
import { Vue, Component, Prop, Emit, Watch } from 'vue-property-decorator';
import './parameter-definition.less';
/**
 * 参数定义组件
 *
 * @export
 * @class ParameterDefinition
 * @extends {Vue}
 */
let ParameterDefinition = class ParameterDefinition extends Vue {
    constructor() {
        super(...arguments);
        /**
         * 是否自定义编写参数
         *
         * @protected
         * @type {boolean}
         * @memberof ParameterDefinition
         */
        this.isCustom = false;
        /**
         * 值
         *
         * @protected
         * @type {string}
         * @memberof ParameterDefinition
         */
        this.$value = '';
        /**
         * 所有定义参数
         *
         * @protected
         * @type {ParameterDefinitionItem[]}
         * @memberof ParameterDefinition
         */
        this.items = [];
        /**
         * 参数类型
         *
         * @protected
         * @memberof ParameterDefinition
         */
        this.paramTypes = {
            default: {
                key: 'default',
                text: '默认',
            },
            context: {
                key: 'context',
                text: '上下文',
            },
            viewParam: {
                key: 'view',
                text: '视图参数',
            },
        };
        /**
         * 值类型
         *
         * @protected
         * @type {*}
         * @memberof ParameterDefinition
         */
        this.valTypes = {
            direct: {
                key: 'direct',
                text: '直接值',
            },
            context_view: {
                key: 'context_view',
                text: '值填充',
                regExp: /^%(.*)%$/,
            },
        };
        /**
         * 参数类型拼接
         *
         * @protected
         * @memberof ParameterDefinition
         */
        this.types = {
            // 上下文模式
            srfNavCtx: 'SRFNAVCTX',
            // 视图参数
            srfNavParam: 'SRFNAVPARAM',
        };
        this.time = null;
    }
    /**
     * 监控值变化
     *
     * @memberof ParameterDefinition
     */
    watchValue() {
        if (!Object.is(this.value, this.$value)) {
            this.$value = this.value;
            this.dataFormat();
        }
    }
    /**
     * 数据变更事件
     *
     * @param {string} val
     * @memberof ParameterDefinition
     */
    dataChange(val) { }
    /**
     * 值变更
     *
     * @protected
     * @memberof ParameterDefinition
     */
    change() {
        if (this.time) {
            clearTimeout(this.time);
            this.time = null;
        }
        this.time = setTimeout(() => {
            this.$value = this.changeFormat();
            const valueData = this.$value === '' ? null : this.$value;
            this.dataChange(valueData);
        }, 500);
    }
    /**
     * 参数格式化
     *
     * @protected
     * @param {string} [str=this.$value]
     * @memberof ParameterDefinition
     */
    dataFormat(str = this.$value) {
        if (str && str !== '') {
            this.items = [];
            const items = str.split(this.separator);
            items.forEach((item) => {
                const arr = item.split('=');
                if (arr.length !== 2) {
                    console.warn('解析失败，参数格式异常：' + item);
                    return;
                }
                let valStr = arr[1];
                const valueType = this.valTypes.context_view.regExp.test(valStr) ? 'context_view' : 'direct';
                if (Object.is(valueType, 'context_view')) {
                    valStr = valStr.replace(/%/g, '');
                }
                let keyStr = arr[0];
                let type = this.paramTypes.default.key;
                if (item.indexOf(this.types.srfNavCtx + '.') !== -1) {
                    type = this.paramTypes.context.key;
                    keyStr = arr[0].split('.')[1];
                }
                else if (item.indexOf(this.types.srfNavParam + '.') !== -1) {
                    type = this.paramTypes.viewParam.key;
                    keyStr = arr[0].split('.')[1];
                }
                this.items.push({
                    type,
                    valueType,
                    keyStr,
                    valStr,
                });
            });
        }
    }
    /**
     * 数据变更格式化
     *
     * @protected
     * @param {ParameterDefinitionItem[]} [items=this.items]
     * @returns {string}
     * @memberof ParameterDefinition
     */
    changeFormat(items = this.items) {
        const arr = items.map((item) => {
            let str = '';
            switch (item.type) {
                case 'context':
                    str += this.types.srfNavCtx + '.';
                    break;
                case 'view':
                    str += this.types.srfNavParam + '.';
                    break;
            }
            return `${str}${item.keyStr}=${Object.is(item.valueType, 'direct') ? item.valStr : `%${item.valStr}%`}`;
        });
        return arr.join(this.separator);
    }
    /**
     * 拷贝相
     *
     * @protected
     * @param {*} item
     * @param {number} i
     * @memberof ParameterDefinition
     */
    copyItem(item, i) {
        this.items.splice(i, 0, Object.assign({}, item));
    }
    /**
     * 删除项
     *
     * @protected
     * @param {number} i
     * @memberof ParameterDefinition
     */
    removeItem(i) {
        this.items.splice(i, 1);
        this.change();
    }
    /**
     * 添加项
     *
     * @protected
     * @memberof ParameterDefinition
     */
    addItem() {
        this.items.push({
            type: 'default',
            valueType: 'direct',
            keyStr: '',
            valStr: '',
        });
    }
    /**
     * 切换展示模式
     *
     * @protected
     * @memberof ParameterDefinition
     */
    changeShowMode() {
        if (this.isCustom) {
            this.dataFormat();
        }
        else {
            this.$value = this.changeFormat();
        }
        this.isCustom = !this.isCustom;
    }
    /**
     * 绘制项
     *
     * @protected
     * @param {ParameterDefinitionItem} item
     * @param {number} i
     * @returns {*}
     * @memberof ParameterDefinition
     */
    renderItem(item, i) {
        const arr = [];
        for (const key in this.paramTypes) {
            const element = this.paramTypes[key];
            arr.push(<i-option value={element.key} key={element.key}>
          {element.text}
        </i-option>);
        }
        const arr2 = [];
        for (const key in this.valTypes) {
            const element = this.valTypes[key];
            arr2.push(<i-option value={element.key} key={element.key}>
          {element.text}
        </i-option>);
        }
        return (<div class='param-item'>
        <div class='item item-type'>
          <i-select on-on-change={() => this.change()} v-model={item.type} size='small'>
            {arr}
          </i-select>
        </div>
        <div class='item item-key'>
          <i-input on-on-change={() => this.change()} v-model={item.keyStr} size='small' placeholder='请输入'/>
        </div>
        <div class='item item-value'>
          <i-input on-on-change={() => this.change()} v-model={item.valStr} size='small' placeholder='请输入'/>
        </div>
        <div class='item item-value-type'>
          <i-select on-on-change={() => this.change()} v-model={item.valueType} size='small'>
            {arr2}
          </i-select>
        </div>
        <div class='item remove' on-click={() => this.removeItem(i)}>
          <icon type='md-close'/>
        </div>
        <div class='item copy' on-click={() => this.copyItem(item, i)}>
          <icon type='md-copy'/>
        </div>
      </div>);
    }
    /**
     * 绘制内容
     *
     * @returns {*}
     * @memberof ParameterDefinition
     */
    render() {
        return (<div class='parameter-definition'>
        {this.isCustom ? (<textarea class='ivu-input' rows={10} v-model={this.$value} on-change={() => this.dataChange(this.$value)} style='height:100px;'></textarea>) : (<div class='param-items'>{this.items.map((item, i) => this.renderItem(item, i))}</div>)}
        <div class='param-add'>
          <i-button size='small' type='default' on-click={() => this.changeShowMode()}>
            {this.isCustom ? '关闭' : '开启'}自定义
          </i-button>
          {this.isCustom ? null : <i-button size='small' type='default' icon='md-add' on-click={() => this.addItem()}/>}
        </div>
      </div>);
    }
};
__decorate([
    Prop({ default: '' })
], ParameterDefinition.prototype, "value", void 0);
__decorate([
    Watch('value', { deep: true, immediate: true })
], ParameterDefinition.prototype, "watchValue", null);
__decorate([
    Prop({ default: '\n' })
], ParameterDefinition.prototype, "separator", void 0);
__decorate([
    Emit('data-change')
], ParameterDefinition.prototype, "dataChange", null);
ParameterDefinition = __decorate([
    Component({})
], ParameterDefinition);
export { ParameterDefinition };
