import axios, { AxiosResponse } from 'axios';
import FileHandle from '../../common/BasicFunctions/Handles/FileHandle'

// 假设这些类型在其他文件中定义
interface AttchedFiles {
    Filedata: number[];
    FiledataLength: number;
}

interface TransitEntity {
    ServiceName: string;
    FuncName: string;
    Parameters?: { [key: string]: string };
    AttachFiles?: AttachFile[];
    Timeout?: number;
}

interface AttachFile {
    AttachIndex: string;
    AttachType: string;
    AttachValue: any;
}

interface PFUsedFileInfo {
    Md5: string;
    // 其他属性根据实际情况添加
}

// 假设这些工具函数在其他文件中定义
class CommonFunction {
    static ChangeEntityToTable(imageList: AttchedFiles[]): any {
        // 实现具体逻辑
        return [];
    }
    static ChangStrToArray(str: string): string[] {
        // 实现具体逻辑
        return [];
    }
    static ChangArrayToStr(arr: string[]): string {
        // 实现具体逻辑
        return '';
    }
    static ChangeTableToEntitys<T>(table: any): T[] {
        // 实现具体逻辑
        return [] as T[];
    }
    static ChangeStrToDic(str: string): { [key: string]: string } {
        // 实现具体逻辑
        return {};
    }
}

class ServiceManager {
    static async Commit(entity: TransitEntity): Promise<AttachFile[]> {
        // 模拟请求
        const response: AxiosResponse<AttachFile[]> = await axios.post('/api/service', entity);
        return response.data;
    }
}

class PlatformLogger {
    static SystemErrorInfo(message: string, error: Error) {
        console.error(message, error);
    }
}

// class FileHandle {
//     static GetFileMD5(fileInfo: any): string {
//         // 实现具体逻辑
//         return '';
//     }
//     static SaveFile(fileInfo: any, data: number[], append: boolean): boolean {
//         // 实现具体逻辑
//         return true;
//     }
// }

class PlatformSettings {
    static PagesDirectory: string = 'pages';
}

export default class FilesHandle {
    static UpdateAssemblys: { [key: string]: boolean } = {};

    static async PutAttachedFiles(imageList: AttchedFiles[]): Promise<string[]> {
        let tradeReturn: string[] | null = null;
        try {
            const entity: TransitEntity = {
                ServiceName: 'ProcessService',
                FuncName: 'PutAttachedFiles',
                AttachFiles: []
            };

            const attcheds: AttachFile = {
                AttachIndex: '1',
                AttachType: 'TableType',
                AttachValue: CommonFunction.ChangeEntityToTable(imageList)
            };
            entity.AttachFiles.push(attcheds);

            const memoryStream = new Uint8Array();
            for (const tmp of imageList) {
                memoryStream.set(tmp.Filedata, memoryStream.length);
            }
            const filedata = new Uint8Array(memoryStream.length);
            filedata.set(memoryStream);

            const attcheds2: AttachFile = {
                AttachIndex: '2',
                AttachType: 'ByteType',
                AttachValue: filedata
            };
            entity.AttachFiles.push(attcheds2);

            const tmpresult = await ServiceManager.Commit(entity);
            if (tmpresult && tmpresult.length === 1) {
                tradeReturn = CommonFunction.ChangStrToArray(tmpresult[0].AttachValue.toString());
            }
        } catch (e) {
            PlatformLogger.SystemErrorInfo('PutAttachedFiles方法出现异常：', e as Error);
            throw e;
        }
        return tradeReturn!;
    }

    static async GetAttachedFiles(fileIDs: string[]): Promise<AttchedFiles[]> {
        let tradeReturn: AttchedFiles[] | null = null;
        try {
            const entity: TransitEntity = {
                ServiceName: 'ProcessService',
                FuncName: 'GetAttachedFiles',
                Parameters: { '1': CommonFunction.ChangArrayToStr(fileIDs) }
            };

            const tmpresult = await ServiceManager.Commit(entity);
            if (tmpresult && tmpresult.length === 2) {
                tradeReturn = CommonFunction.ChangeTableToEntitys<AttchedFiles>(tmpresult[0].AttachValue as any);
                if (tradeReturn) {
                    let i = 0;
                    for (const tmp of tradeReturn) {
                        tmp.Filedata = new Array(tmp.FiledataLength);
                        // tmp.Filedata.set(tmpresult[1].AttachValue.slice(i, i + tmp.FiledataLength));TODO
                        i += tmp.FiledataLength;
                    }
                }
            }
        } catch (e) {
            PlatformLogger.SystemErrorInfo('GetAttachedFiles方法出现异常：', e as Error);
            throw e;
        }
        return tradeReturn!;
    }

    static async CheckMD5(localFilePath: string, serverFilePath: string): Promise<boolean> {
        let result = false;
        try {
            const entity: TransitEntity = {
                ServiceName: 'UtilService',
                FuncName: 'GetFileMD5',
                Parameters: { '1': serverFilePath }
            };

            const tmpresult = await ServiceManager.Commit(entity);
            if (tmpresult && tmpresult.length === 1) {
                const serverMd5 = tmpresult[0].AttachValue as string;
                const fileInfo = new FileHandle();
                const localMd5 = "";// fileInfo.GetFileMD5(localFilePath);//微软自带的fileInfo TODO
                result = localMd5.toUpperCase() === serverMd5.toUpperCase();
            }
        } catch (e) {
            PlatformLogger.SystemErrorInfo('GetFileMD5方法出现异常：', e as Error);
            throw e;
        }
        return result;
    }

    static async UpdateTradeDll(actionName: string): Promise<boolean> {
        if (this.UpdateAssemblys[actionName]) {
            delete this.UpdateAssemblys[actionName];
        }

        let result = false;
        try {
            const fileName = `${actionName}.dll`;
            const localFilePath = `${process.cwd()}/${PlatformSettings.PagesDirectory}/${fileName}`;

            const localFile = new FileHandle();
            if (localFile) {
                const files = await this.GetUsedFilesInfo(`/${PlatformSettings.PagesDirectory}`, fileName, '1');
                if (files.length === 1) {
                    const localMd5 = "";// localFile.GetFileMD5(localFilePath);////微软自带的fileInfo TODO
                    const serverMd5 = files[0].Md5;
                    if (localMd5.toUpperCase() === serverMd5.toUpperCase()) {
                        this.UpdateAssemblys[actionName] = false;
                        return true;
                    }
                } else {
                    this.UpdateAssemblys[actionName] = false;
                    return false;
                }
            }

            const data = await this.GetDllFile(fileName, `/${PlatformSettings.PagesDirectory}`);
            if (data) {
                result = true;// localFile.SaveFile(localFilePath, data, false);//localFile TODO
                this.UpdateAssemblys[actionName] = true;
            }
        } catch (e) {
            PlatformLogger.SystemErrorInfo('更新DLL文件UpdateTradeDll方法出现异常：', e as Error);
        }
        return result;
    }

    static async GetDllFile(fileName: string, filePath: string): Promise<number[] | null> {
        let result: number[] | null = null;
        try {
            const entity: TransitEntity = {
                ServiceName: 'PlatFormService',
                FuncName: 'GetDllFile',
                Parameters: { '1': fileName, '2': filePath }
            };

            const tmpresult = await ServiceManager.Commit(entity);
            if (tmpresult && tmpresult.length === 1) {
                result = tmpresult[0].AttachValue as number[];
            }
        } catch (e) {
            PlatformLogger.SystemErrorInfo('GetDllFile方法出现异常：', e as Error);
            throw e;
        }
        return result;
    }

    static async GetServerFileNames(serverFilePath: string): Promise<{ [key: string]: string } | null> {
        let tradeReturn: { [key: string]: string } | null = null;
        if (!serverFilePath) {
            throw new Error('参数不能为空');
        }
        try {
            const entity: TransitEntity = {
                ServiceName: 'UtilService',
                FuncName: 'GetListFileNames',
                Parameters: { '1': serverFilePath }
            };

            const tmpresult = await ServiceManager.Commit(entity);
            if (tmpresult && tmpresult.length === 1) {
                tradeReturn = CommonFunction.ChangeStrToDic(tmpresult[0].AttachValue.toString());
            }
        } catch (e) {
            PlatformLogger.SystemErrorInfo('GetListFileNames方法出现异常：', e as Error);
            throw e;
        }
        return tradeReturn;
    }

    static async SaveFileData(serverFilePath: string, fileData: number[], append: boolean): Promise<boolean> {
        let tradeReturn = false;
        try {
            const entity: TransitEntity = {
                ServiceName: 'UtilService',
                FuncName: 'SaveFile',
                Parameters: { '1': serverFilePath, '3': append.toString() },
                AttachFiles: []
            };

            const file: AttachFile = {
                AttachIndex: '2',
                AttachType: 'ByteType',
                AttachValue: fileData
            };
            entity.AttachFiles.push(file);

            const tmpresult = await ServiceManager.Commit(entity);
            if (tmpresult && tmpresult.length === 1) {
                tradeReturn = Boolean(tmpresult[0].AttachValue);
            }
        } catch (e) {
            PlatformLogger.SystemErrorInfo('SaveFile方法出现异常：', e as Error);
            throw e;
        }
        return tradeReturn;
    }

    static async DownloadFile(localFilePath: string, serverFilePath: string): Promise<boolean> {
        let SaveFileresult;
        try {
            if (!serverFilePath || !localFilePath) {
                throw new Error('参数不能为空');
            }

            const result = await this.GetFileData(serverFilePath);
            if (result && result.length > 0) {
                //const fileHandle = new FileHandle();
                SaveFileresult = FileHandle.SaveFile(localFilePath, result, false);//类中的GetFileData的将原来的byte转换成额buffer
            }
        } catch (e) {
            PlatformLogger.SystemErrorInfo('DownloadFile方法出现异常：', e as Error);
            throw e;
        }
        return SaveFileresult;
    }

    static async GetFileData(serverFilePath: string): Promise<Buffer | null> {
        const size = 1024 * 50;
        let tradeReturn: Buffer | null = null;
        let len = 0;
        try {
            len = await this.GetFileBlockLength(serverFilePath);

            if (len <= size) {
                const entity2: TransitEntity = {
                    ServiceName: 'UtilService',
                    FuncName: 'GetFile',
                    Parameters: { '1': serverFilePath },
                    Timeout: 10000
                };

                const tmpresult2 = await ServiceManager.Commit(entity2);
                if (tmpresult2 && tmpresult2.length === 1) {
                    tradeReturn = tmpresult2[0].AttachValue as Buffer;
                }
            } else {
                //tradeReturn = new Array(len);
                let offset = 0;
                while (offset < len) {
                    const lens = len - offset > size ? size : len - offset;
                    const result = await this.GetFileBlock(serverFilePath, offset, lens);
                    //tradeReturn.set(result, offset);TODO
                    offset += size;
                }
            }
        } catch (e) {
            PlatformLogger.SystemErrorInfo('GetFile方法出现异常：', e as Error);
            throw e;
        }
        return tradeReturn;
    }

    static async GetUsedFilesInfo(fileName: string, filePath: string, fileType: string): Promise<PFUsedFileInfo[]> {
        let result: PFUsedFileInfo[] | null = null;
        try {
            const entity: TransitEntity = {
                ServiceName: 'PlatFormService',
                FuncName: 'GetUsedFilesInfo',
                Parameters: { '1': fileName, '2': filePath, '3': fileType }
            };

            const tmpresult = await ServiceManager.Commit(entity);
            if (tmpresult && tmpresult.length === 1) {
                result = CommonFunction.ChangeTableToEntitys<PFUsedFileInfo>(tmpresult[0].AttachValue as any);
            }
        } catch (e) {
            PlatformLogger.SystemErrorInfo('GetUsedFilesInfo方法出现异常：', e as Error);
            throw e;
        }
        return result!;
    }

    static async GetFileBlock(fileName: string, offset: number, length: number): Promise<number[] | null> {
        let result: number[] | null = null;
        try {
            const entity: TransitEntity = {
                ServiceName: 'UtilService',
                FuncName: 'GetFileByLength',
                Parameters: { '1': fileName, '2': offset.toString(), '3': length.toString() },
                Timeout: 10000
            };

            const tmpresult = await ServiceManager.Commit(entity);
            if (tmpresult && tmpresult.length === 1) {
                result = tmpresult[0].AttachValue as number[];
            }
        } catch (e) {
            PlatformLogger.SystemErrorInfo('GetFileByLength方法出现异常：', e as Error);
            throw e;
        }
        return result;
    }

    static async GetFileBlockLength(fileName: string): Promise<number> {
        let len = 0;
        try {
            const entity: TransitEntity = {
                ServiceName: 'UtilService',
                FuncName: 'GetFileLength',
                Parameters: { '1': fileName }
            };

            const tmpresult = await ServiceManager.Commit(entity);
            if (tmpresult && tmpresult.length === 1) {
                len = Number(tmpresult[0].AttachValue);
            }
        } catch (e) {
            PlatformLogger.SystemErrorInfo('GetFileLength方法出现异常：', e as Error);
            throw e;
        }
        return len;
    }
}
