import { reactive } from 'vue'

/**
 * 复核岗复核元素和回显元素的数据项集合
 */
export class CheckElements {
    private document: Document
    private root: Element
    private nodeList: Element[] = []

    constructor() {
        // 创建XML文档
        this.document = document.implementation.createDocument("", "root", null)
        this.root = this.document.documentElement!
        
        // 添加XML声明
        const declaration = this.document.createProcessingInstruction(
            "xml", 
            'version="1.0" encoding="GB2312"'
        )
        this.document.insertBefore(declaration, this.root)
    }

    /**
     * 增加要复核或显示给复核岗看的项
     * @param label 标签
     * @param text 文本值
     * @param checkLabel 是否需要复核柜员复核的数据项
     * @param inputType 此数据的数据类型
     * @param IsToSbc 是否转换为全角
     * @param dict 字典数据
     */
    public AddElement(
        label: string, 
        text: string, 
        checkLabel: string, 
        inputType: number, 
        IsToSbc: boolean = false, 
        dict?: Map<string, string>
    ): void {
        const element = this.document.createElement("Element")
        
        // 设置属性
        element.setAttribute("Label", label)
        element.setAttribute("CheckLabel", checkLabel)
        element.setAttribute("InputType", inputType.toString())
        element.setAttribute("IsToSbc", IsToSbc.toString())
        
        // 处理字典数据
        let dictValue = ""
        if (dict) {
            dict.forEach((value, key) => {
                dictValue += `${key}|${value}\n`
            })
        }
        element.setAttribute("dict", dictValue)
        
        // 设置文本内容
        element.textContent = text
        
        this.nodeList.push(element)
        this.root.appendChild(element)
    }

    /**
     * 获得所有待复合对象集合
     */
    get Xelement(): Element[] {
        return [...this.nodeList]
    }

    /**
     * 获取用string表示的xml文档，在拼到总线上用
     */
    get XmlString(): string {
        const serializer = new XMLSerializer()
        return serializer.serializeToString(this.document)
    }
}

// Vue组合式API封装
export const useCheckElements = () => {
    return reactive(new CheckElements())
}