import OSS, { PutObjectOptions } from "ali-oss";
import Parse from "parse";


export class ProvierOssAli{
    client:OSS|undefined
    async initClient(){
        if(this.client) return
        // 获取STS临时口令
        let result:any = await Parse.Cloud.run("aliOssSTS");
        this.client = new OSS({
            // yourRegion填写Bucket所在地域。以华东1（杭州）为例，yourRegion填写为oss-cn-hangzhou。
            region: "oss-cn-beijing",
            // 从STS服务获取的临时访问密钥（AccessKey ID和AccessKey Secret）。
            accessKeyId: result?.AccessKeyId,
            accessKeySecret: result?.AccessKeySecret,
            // 从STS服务获取的安全令牌（SecurityToken）。
            stsToken: result?.SecurityToken,
            // 填写Bucket名称。
            bucket: result?.ALI_OSS_BUCKET || "hep-textbook",
            timeout:5000*1000
        });
    }
    constructor(){
    }

    /**
     * 上传函数：可单独设置对象私有属性
     * @param file 
     * @param onProcess 
     * @param options 
     * @returns 
     * @example
     * // 普通上传
     * let r1 = await upload(file)
     * // 私密上传 - 单个对象设置私密，需要临时签名URL下载
     * let r2 = await upload(file,null,{acl:"private"})
     */
    async upload(file:File,onProcess?:Function,options?:any){
        await this.initClient();
        let now = new Date();
        let fname = `${Parse.User.current()?.id}/${now.getFullYear()}-${now.getMonth()+1}-${now.getDate()}/${now.getTime()}-${file?.name}`;
        let putOptions:any = {headers:{}}
        if(options?.acl){
            if(!putOptions.headers) putOptions.headers = {}
            putOptions.headers["x-oss-object-acl"] = options?.acl
        }
        const r1 = await this.client?.put(fname, file, putOptions);
        console.log(file)
        console.log('put success: %j', r1);
        return r1
    }

  

    /**
     * 下载函数：可自动识别是否加密，获取私密签名
     * @desc 判断URL是否可下载，若私有则临时授权
     * @param fileUrl 必填，直接下载URL
     * @param fileName 选填，指定下载文件名
     * @example
     */
    async download(fileUrl:string,fileName?:string){
        let response = await fetch(fileUrl)
        if(response?.status==403){
           let tempUrl = await this.signatureUrl(fileUrl);
           if(tempUrl){
               response = await fetch(tempUrl)
            }
        }
        if (!response.ok) {
            console.log(response)
            throw new Error('Network response was not ok');
        }

        try {
            let blob = await response.blob(); // 将响应转换为blob
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            if(fileName){
                a.download = fileName;
            }
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            window.URL.revokeObjectURL(url);
        }catch(error){
            console.error(error);
            throw error;
        }
    }
      // 获取临时签名地址
      async signatureUrl(url:string,options?:any):Promise<string|undefined>{
        let expires = options?.expires || 600 // 默认10分钟
        await this.initClient();
        let urlObj = new URL(url)
        // let r1 = await this.client?.get(fname, file, putOptions);
        let fileKey = decodeURIComponent(urlObj.pathname)
        let r1 = await this.client?.signatureUrl(fileKey, {
             expires: expires,
        });
        console.log(r1)
        return r1;
    }
    // 设置已上传URL为私有文件
    async setACLPrivate(url:string){
        await this.initClient();
        let urlObj = new URL(url);
        console.log(url,urlObj.pathname)
        let fileKey = decodeURIComponent(urlObj.pathname)
        let r1 = await this.client?.putACL(fileKey,"private")
        return r1
    }
    async setACLPublic(url:string){
        await this.initClient();
        let urlObj = new URL(url);
        let fileKey = decodeURIComponent(urlObj.pathname)
        let r1 = await this.client?.putACL(fileKey,"public-read-write")
        return r1
    }

}