import { immutable, excludedInJSON, action } from '../decorators';
import { config, LEVEL_ENUM, ProcessComponent, Vertex, ActionOptions } from '..';
import processService from '../../service/process';

/**
 * 流程节点属性
 */
export class ProcessComponentAttribute extends Vertex {
    /**
     * 概念类型
     */
    @immutable()
    public readonly level: LEVEL_ENUM = LEVEL_ENUM.processComponentAttribute;
    /**
     * 流程节点属性类型
     */
    @immutable()
    public readonly type: 'Destination' = undefined;
    /**
     * 名称
     */
    @immutable()
    public readonly name: string = undefined;
    /**
     * 关联页面属性
     */
    @immutable()
    public readonly pageRef: string = undefined;
    /**
     * 关联页面路由
     */
    @immutable()
    public readonly url: string = undefined;
    /**
     * 流程组件 Id
     */
    @immutable()
    public readonly processComponentId: string = undefined;
    /**
     * 流程组件 Id
     */
    @immutable()
    public readonly destinationParams: Array<any> = [];
    /**
     * 流程节点
     */
    @excludedInJSON()
    @immutable()
    public readonly processComponent: ProcessComponent = undefined;
    /**
     * @param source 需要合并的部分参数
     */
    constructor(source?: Partial<ProcessComponentAttribute>) {
        super();
        source && this.assign(source);
    }
    /**
     * 创建流程节点属性类型
     */
    @action('创建流程节点属性类型')
    async create() {
        const body = this.toJSON();
        const result = await processService.addProcessAttribute({
            body,
        });
        this.assign(result);
        this.processComponent.assign({
            destination: this,
        });
        ProcessComponentAttribute.checkType(this.id, this.processComponent);
        return this;
    }
    /**
     * 删除流程节点属性类型
     */
    @action('删除流程节点属性类型')
    async delete() {
        if (this.id) {
            await processService.deleteProcessAttribute({ path: { id: this.id } });
            this.processComponent.assign({
                destination: null,
            });
        }
        this.destroy();
    }
    /**
     * 更新流程节点属性类型
     */
    @action('更新流程节点属性类型')
    async update(none?: void, actionOptions?: ActionOptions) {
        if (this.id) {
            config.defaultApp?.emit('saving');

            const body = this.toJSON();
            const result = await processService.updateProcessAttribute({
                headers: {
                    appId: config.defaultApp?.id,
                    operationAction: actionOptions?.actionName || 'ProcessComponentAttribute.update',
                    operationDesc: actionOptions?.actionDesc || `更新流程节点属性类型"${this.name}"`,
                },
                body,
            });
            this.assign(result);
            ProcessComponentAttribute.checkType(this.id, this.processComponent);

            await config.defaultApp?.history.load();
            config.defaultApp?.emit('saved');
        }
    }
    /**
     * 流程节点属性类型检查
     */
    public static async checkType(id: string, processComponent: ProcessComponent) {
        const result = await processService.checkTypeProcessAttribute({
            path: { id },
        });
        ProcessComponent.assignTypeCheckResult(processComponent, result);
    }
    /**
     * 从后端 JSON 生成规范的 ProcessComponentAttribute 对象
     */
    public static from(source: any, processComponent: ProcessComponent) {
        const processComponentVariable = new ProcessComponentAttribute(source);
        processComponentVariable.assign({
            processComponent,
        });
        return processComponentVariable;
    }
}

export default ProcessComponentAttribute;
