import { immutable } from '../decorators';
import { config, LEVEL_ENUM, Vertex, PackageJSON, App, WebService, Page, Element, Logic, Param, Variable, ViewParam, Lifecycle } from '..';

/**
 * 区块类
 */
export class Block extends Vertex {
    /**
     * 概念类型
     */
    @immutable()
    public readonly level: LEVEL_ENUM = LEVEL_ENUM.block;
    /**
     * 子页面 Id
     */
    @immutable()
    public readonly id: string;
    /**
     * 子页面标识（路径）
     */
    @immutable()
    public readonly name: string;
    /**
     * 标题
     */
    @immutable()
    public readonly title: string;
    /**
     * 模板源码
     */
    public template: string;
    /**
     * 模板 AST
     */
    @immutable()
    public readonly $html: Element;
    /**
     * 定义源码
     */
    @immutable()
    public readonly definition: string;
    /**
     * 逻辑相关定义
     */
    @immutable()
    public readonly $def: {
        logics: Array<Logic>,
        params: Array<ViewParam>,
        variables: Array<Variable>,
        lifecycles: Array<Lifecycle>,
    } = {
        logics: [],
        params: [],
        variables: [],
        lifecycles: [],
    };
    /**
     * 样式补充
     * 最好直接在标签上添加逻辑，这里只是偶尔做额外补充
     */
    @immutable()
    public readonly style: string;
    /**
     * 逻辑补充
     * 最好直接使用逻辑 ASL，这里只是偶尔做代码补充
     */
    @immutable()
    public readonly script: string;
    /**
     * @param source 需要合并的部分参数
     */
    constructor(source?: Partial<Block>) {
        super();
        source && this.assign(source);
    }

    /**
     * 从模板解析出 AST
     * @param template 模板代码
     */
    parseTemplate(template?: string) {
        template = template || this.template || '<div></div>';

        this.assign({ $html: Element.parse(template) });
    }

    parseDefinition(definition: string = this.definition) {
        definition = definition || this.definition || '{}';

        this.assign({ $def: JSON.parse(definition) });
    }

    parseAll() {
        this.parseTemplate();
        this.parseDefinition();
    }

    // traverseTemplate() {

    // }
}

export default Block;
