import http from "@ohos:net.http";
import request from "@ohos:request";
import { RequestBody } from "@normalized:N&&&@yic/http/src/main/ets/requestbody/RequestBody&1.0.1";
import { Process, ProcessStatus } from "@normalized:N&&&@yic/http/src/main/ets/core/Model&1.0.1";
import { HttpConfig } from "@normalized:N&&&@yic/http/src/main/ets/core/HttpConfig&1.0.1";
/**
 * @ProjectName : HarmonyUtilSdk
 * @FileName : UploadRequestBody
 * @Author : yic
 * @Time : 2024/6/21 9:51
 * @Description : 文件描述
 */
export default class UploadRequestBody extends RequestBody {
    protected files = new Array<request.File>();
    private processCallback?: (process: Process) => void;
    constructor(url: string) {
        super(url, http.RequestMethod.POST);
    }
    addFile(name: string, path: string): UploadRequestBody {
        let fileName = path.substring(path.lastIndexOf('/') + 1);
        let type = path.substring(path.lastIndexOf('.') + 1);
        this.files.push({
            filename: fileName,
            name: name,
            uri: path,
            type: type
        });
        return this;
    }
    getFiles(): Array<request.File> {
        return this.files;
    }
    setUploadCallback(processCallback: (process: Process) => void) {
        this.processCallback = processCallback;
    }
    protected call(): Promise<http.HttpResponse> {
        return new Promise<http.HttpResponse>((resolve, reject) => {
            let url = this.getUrl();
            request.uploadFile(getContext(this), {
                url: url,
                header: { ...this.getHeader() },
                method: 'POST',
                data: this.toRequestData(this.getParam()),
                files: this.getFiles()
            }).then((task) => {
                let start = new Date().getTime();
                let lastReceivedSize = 0;
                let process = new Process();
                //添加所有监听
                task.on('progress', (receivedSize, totalSize) => {
                    if (this.isCancel()) {
                        console.info('canceled', this.getUrlWithParam());
                        //任务分发结束当前任务
                        HttpConfig.getInstance().getTaskDispatch().done(this);
                        //http中任务删除
                        task.delete();
                        return;
                    }
                    let now = new Date().getTime();
                    let intervalByteCount = lastReceivedSize === 0 ? 0 : receivedSize - lastReceivedSize;
                    let intervalTime = now - start;
                    lastReceivedSize = receivedSize;
                    start = now;
                    process.currentByteCount = receivedSize;
                    process.totalByteCount = totalSize;
                    process.intervalByteCount = intervalByteCount;
                    process.intervalTime = intervalTime;
                    process.status = ProcessStatus.PROCESSING;
                    this.processCallback && this.processCallback(process);
                });
                task.on('complete', (arr) => {
                    process.status = ProcessStatus.COMPLETED;
                    this.processCallback && this.processCallback(process);
                    const response: http.HttpResponse = {
                        result: JSON.stringify(process),
                        resultType: http.HttpDataType.STRING,
                        responseCode: http.ResponseCode.OK,
                        header: {},
                        cookies: ''
                    };
                    resolve(response);
                });
                task.on('fail', (err) => {
                    console.error('download fail', JSON.stringify(err));
                    process.status = this.isCancel() ? ProcessStatus.CANCEL : ProcessStatus.FAILED;
                    this.processCallback && this.processCallback(process);
                    reject(JSON.stringify(process));
                });
            });
        });
    }
    /**
     * 将参数保存到RequestData数组
     * @param params
     * @returns
     */
    private toRequestData(params: any): Array<request.RequestData> {
        let data: request.RequestData[] = [];
        Object.keys(params).forEach((key) => {
            data.push({
                name: key,
                value: params[key]
            });
        });
        return data;
    }
}
