import { SendCodeDto } from './../sms/dto/sms.dto'
import { Inject, Injectable, InternalServerErrorException, Logger, NotAcceptableException } from '@nestjs/common'
import aliyunConfig from './config/aliyun.config'
import { ConfigType } from '@nestjs/config'
import Dysmsapi20170525, * as $Dysmsapi20170525 from '@alicloud/dysmsapi20170525'
import OpenApi, * as $OpenApi from '@alicloud/openapi-client'
import Util, * as $Util from '@alicloud/tea-util'
import * as $tea from '@alicloud/tea-typescript'
import { SendSmsResponse } from '@alicloud/dysmsapi20170525'
import * as randomstring from 'randomstring'
import * as OSS from 'ali-oss'
import { buffer } from 'stream/consumers'
import { AfsClient, AuthenticateSigRequest, AuthenticateSigResponse } from './afs'

@Injectable()
export class AliyunService {
    constructor(
        @Inject(aliyunConfig.KEY)
        private readonly aliyunConfiguration: ConfigType<typeof aliyunConfig>
    ) {}

    public async sendCode(data: SendCodeDto) {
        //await this.authSig(data.sessionId, data.sig, data.token)
        if (!/^1[3-9]\d{9}$/.test(data.phone)) {
            throw new InternalServerErrorException('手机号码格式不正确')
        }
        let config = new $OpenApi.Config({
            accessKeyId: this.aliyunConfiguration.accessKeyId,
            accessKeySecret: this.aliyunConfiguration.accessKeySecret
        })
        config.endpoint = `dysmsapi.aliyuncs.com`
        let client = new Dysmsapi20170525(config)
        const code = randomstring.generate({ length: 4, charset: 'numeric' })
        let sendSmsRequest = new $Dysmsapi20170525.SendSmsRequest({
            phoneNumbers: data.phone,
            signName: this.aliyunConfiguration.smsSign,
            templateCode: this.aliyunConfiguration.smsTemplateCode,
            templateParam: JSON.stringify({ code })
        })
        try {
            const res: SendSmsResponse = await client.sendSmsWithOptions(sendSmsRequest, new $Util.RuntimeOptions({}))
            if (res.statusCode === 200 && res.body.code == 'OK') {
                return { phone: data.phone, code }
            } else {
                throw new InternalServerErrorException(res.body.message)
            }
        } catch (error) {
            Logger.error(error.message)
            throw new InternalServerErrorException(error.message)
        }
    }

    public async uploadFile(path: string, data: Buffer) {
        let client = new OSS({
            endpoint: this.aliyunConfiguration.ossEndPoint,
            accessKeyId: this.aliyunConfiguration.accessKeyId,
            accessKeySecret: this.aliyunConfiguration.accessKeySecret,
            bucket: this.aliyunConfiguration.ossBucket
        })
        try {
            const result = await client.put(path, data)
            Logger.log(result)
            if (result.res.status === 200) {
                return { url: result.url.replace('http:', 'https:') }
            } else {
                throw new InternalServerErrorException(result.res.statusMessage)
            }
        } catch (e) {
            Logger.error(e)
            throw new InternalServerErrorException(e.message)
        }
    }

    public async authSig(sessionId: string, sig: string, token: string) {
        var client = new AfsClient({
            accessKeyId: this.aliyunConfiguration.accessKeyId,
            accessKeySecret: this.aliyunConfiguration.accessKeySecret,
            endpoint: 'afs.aliyuncs.com',
            regionId: 'cn-hangzhou',
            toMap: null
        })
        // AuthenticateSigRequest
        var data = new AuthenticateSigRequest({
            scene: 'nc_activity_h5',
            sessionId: sessionId,
            sig: sig,
            appKey: 'FFFF0N0000000000B53B',
            token: token,
            remoteIp: '192.168.0.11'
        })
        try {
            const res: AuthenticateSigResponse = await client.authenticateSig(data)
            if (res.body.code === 100) {
                return
            } else {
                Logger.error(res.body.msg)
                throw new NotAcceptableException('验证失败')
            }
        } catch (e) {
            Logger.error(e)
            throw new InternalServerErrorException(e.message)
        }
    }
}
