
import TransitEntity from '../ServiceFunction/TransitEntity';
import ServiceManager from '../ServiceFunction/ServiceManager';
import CommonFunction from '../CommonFunction';
import FilesHandle from '../ServiceHelper/FilesHandle'

//import { CommonParames, TradeParames } from '../../Common/RunningParameters/CommonParames';

// 假设这些类型和方法在其他文件中定义 TODO 
// interface TransitEntity {
//     ServiceName: string;
//     FuncName: string;
//     Parameters?: { [key: string]: string };
// }

interface AttachFile {
    AttachValue: any;
}


// 假设这些全局参数在其他文件中定义
namespace CommonParames {
    export let MsgErrorMap: { [key: string]: string };
    export let Coding: string;
    export let SysName: string;
    export let UpdatedClientPath: string;
    export let TradeInfoPath: string;
    export let ConfigFilePath: string;
    export let TempFilePath: string;
    export let TellerSysHelp: string;
}

namespace TradeParames {
    export let MsgFormat: { [key: string]: { [key: string]: any } };
}

export class InitializeHandle {
    static async InitMsgFormat() {
        if (!TradeParames.MsgFormat) {
            // TradeParames.MsgFormat = await this.GetMessageFormatMap();//TODO
        }
    }

    static async InitErrorMap() {
        if (!CommonParames.MsgErrorMap) {
            CommonParames.MsgErrorMap = await this.GetErrorMap();
        }
    }

    static async InitConfig() {
        try {
            let result: string | null = null;
            const entity: TransitEntity = {
                ServiceName: "CommonService",
                FuncName: "GetClientConfig",
                Parameters: {},
                AttachFiles: null,
                Timeout: 10000
            };
            const tmpresult = ServiceManager.GetInstance().Commit(entity);
            if (tmpresult && tmpresult.length === 1) {
                result = tmpresult[0].AttachValue as string;
            }

            const dict = CommonFunction.ChangeStrToDic(result);
            // 初始化配置文件
            CommonParames.Coding = dict["CharacterSet"];
            CommonParames.SysName = dict["MsgTitle"];
            CommonParames.UpdatedClientPath = dict["UpdatedClientPath"];
            CommonParames.TradeInfoPath = dict["TradeInfoPath"];
            CommonParames.ConfigFilePath = dict["ConfigFilePath"];
            CommonParames.TempFilePath = dict["TempFilePath"];
            CommonParames.TellerSysHelp = dict["TellerSysHelp"];
        } catch (e) {
            throw e;
        }
        return true;
    }

    static async GetFdItemMap() {
        const table: { [key: string]: string }[] = [];
        const entity: TransitEntity = {
            ServiceName: "TradeService",
            FuncName: "GetFdItemMap",
            Parameters: {},
            AttachFiles: null,
            Timeout: 10000
        };
        const tmpresult = ServiceManager.GetInstance().Commit(entity);
        let data: string | null = null;
        if (tmpresult && tmpresult.length === 1) {
            data = tmpresult[0].AttachValue as string;
        }
        if (data) {
            const lines = data.split('\n');
            for (const line of lines) {
                if (line) {
                    const rows = line.split('|');
                    const item = {
                        Code: rows[0],
                        Type: rows[1],
                        Length: rows[2],
                        DotLength: rows[3],
                        Description: rows[4],
                        FieldType: rows[5],
                        MaxLength: rows[6],
                        DataName: rows[7]
                    };
                    table.push(item);
                }
            }
        }
        return table;
    }

    static async GetMessageFormatMap() {
        // const messageFormatMap: { [key in Transit]: { [key: string]: any } } = {} as any;
        // const transits = Object.values(Transit);
        // for (const transit of transits) {
        //    const dictionary = await this.GetTradeMessageFormat(transit.toString());
        //    if (dictionary && Object.keys(dictionary).length > 0) {
        //        messageFormatMap[transit as Transit] = dictionary;
        //    }
        //  }
        return "";
    }

    static async GetTradeMessageFormat(transitName: string) {
        let dictionary: { [key: string]: any } | null = null;
        try {
            const entity: TransitEntity = {
                ServiceName: "TradeService",
                FuncName: "GetTradeMessageFormat",
                Parameters: { "1": transitName },
                AttachFiles: null,
                Timeout: 10000
            };
            const tmpresult = ServiceManager.GetInstance().Commit(entity);
            if (tmpresult && tmpresult.length === 1) {
                dictionary = CommonFunction.ChangeStrToDic(tmpresult[0].AttachValue.toString());
            }
        } catch (e) {
            throw e;
        }
        return dictionary;
    }

    static async GetErrorMap() {
        // TODO: 暂时先这样处理，考虑移动到更新管理中去
        const localPath = `${process.cwd()}/errorMap.xml`;
        const serverPath = `${CommonParames.ConfigFilePath}errorMap.xml`;
        const fs = require('fs').promises;
        const isFileValid = await FilesHandle.CheckMD5(localPath, serverPath);
        if (!fs.existsSync(localPath) || !isFileValid) {
            // 更新文件
            if (fs.existsSync(localPath)) {
                await fs.unlink(localPath);
            }
            const data = await FilesHandle.GetFileData(serverPath);
            await fs.writeFile(localPath, Buffer.from(data));
        }
        // 读取配置文件
        const dictionary: { [key: string]: string } = {};
        const xml = await fs.readFile(localPath, 'utf-8');
        const DOMParser = require('xmldom').DOMParser;
        const document = new DOMParser().parseFromString(xml, 'text/xml');
        const root = document.documentElement;
        if (root) {
            for (let i = 0; i < root.childNodes.length; i++) {
                const node = root.childNodes[i];
                if (node.nodeName === "error") {
                    const name = node.attributes.getNamedItem("name")?.value;
                    const value = node.attributes.getNamedItem("value")?.value;
                    if (name && value) {
                        dictionary[name] = value;
                    }
                }
            }
        }
        return dictionary;
    }
}
