package sms

import (
	"encoding/json"
	"fmt"
	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	dysmsapi20170525 "github.com/alibabacloud-go/dysmsapi-20170525/v5/client"
	util "github.com/alibabacloud-go/tea-utils/v2/service"
	"github.com/alibabacloud-go/tea/tea"
	credential "github.com/aliyun/credentials-go/credentials"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/os/glog"
	"strings"
	"yx-dataset-server/app/errors"
)

type ALiYunSendSmsArgs struct {
	TemplateCode  string `json:"template_code"`
	PhoneNumbers  string `json:"phone_numbers"`
	TemplateParam string `json:"template_param"`
}

type ALiYunSendBatchSmsArgs struct {
	TemplateCode  string `json:"template_code"`
	PhoneNumbers  string `json:"phone_numbers"`
	TemplateParam string `json:"template_param"`
}

// Description:
//
// 使用凭据初始化账号Client
//
// @return Client
//
// @throws Exception
func CreateClient() (result *dysmsapi20170525.Client, err error) {
	// 工程代码建议使用更安全的无AK方式，凭据配置方式请参见：https://help.aliyun.com/document_detail/378661.html。
	//credential, err := credential.NewCredential(nil)
	//if err != nil {
	//	return result, err
	//}
	//
	//config := &openapi.Config{
	//	Credential:      credential,
	//	AccessKeyId:     tea.String(g.Cfg().GetString("aliyun_sms.accessKeyId")),
	//	AccessKeySecret: tea.String(g.Cfg().GetString("aliyun_sms.accessKeySecret")),
	//}
	//// Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
	//config.Endpoint = tea.String("dysmsapi.aliyuncs.com")
	//result = &dysmsapi20170525.Client{}
	//result, err = dysmsapi20170525.NewClient(config)
	//return result, err

	credentialsConfig := new(credential.Config).
		// 凭证类型。
		SetType("access_key").
		// 设置为AccessKey ID值。
		SetAccessKeyId(g.Cfg().GetString("aliyun_sms.accessKeyId")).
		// 设置为AccessKey Secret值。
		SetAccessKeySecret(g.Cfg().GetString("aliyun_sms.accessKeySecret"))
	credentialClient, _err := credential.NewCredential(credentialsConfig)
	if _err != nil {
		panic(_err)
	}
	ecsConfig := &openapi.Config{}
	ecsConfig.Endpoint = tea.String("dysmsapi.aliyuncs.com")
	ecsConfig.Credential = credentialClient
	result, err = dysmsapi20170525.NewClient(ecsConfig)
	return result, err
}

func SendSms(args ALiYunSendSmsArgs) error {
	client, err := CreateClient()
	if err != nil {
		return err
	}

	sendSmsRequest := &dysmsapi20170525.SendSmsRequest{
		SignName:      tea.String(g.Cfg().GetString("aliyun_sms.signName")),
		TemplateCode:  tea.String(args.TemplateCode),
		PhoneNumbers:  tea.String(args.PhoneNumbers),
		TemplateParam: tea.String(args.TemplateParam),
	}

	// 复制代码运行请自行打印 API 的返回值
	d, err := client.SendSmsWithOptions(sendSmsRequest, &util.RuntimeOptions{})
	if err != nil {
		return err
	}
	if d != nil && *d.Body.Message != "OK" {
		glog.Infof("短信发送失败：%s", *d.Body.Message)
		return errors.New400Response(fmt.Sprintf("发送失败：%s,请稍后重试", *d.Body.Message))

	}
	return nil

	//if tryErr != nil {
	//	var error = &tea.SDKError{}
	//	if _t, ok := tryErr.(*tea.SDKError); ok {
	//		error = _t
	//	} else {
	//		error.Message = tea.String(tryErr.Error())
	//	}
	//	// 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
	//	// 错误 message
	//	fmt.Println(tea.StringValue(error.Message))
	//	// 诊断地址
	//	var data interface{}
	//	d := json.NewDecoder(strings.NewReader(tea.StringValue(error.Data)))
	//	d.Decode(&data)
	//	if m, ok := data.(map[string]interface{}); ok {
	//		recommend, _ := m["Recommend"]
	//		fmt.Println(recommend)
	//	}
	//	_, err = util.AssertAsString(error.Message)
	//	if err != nil {
	//		return err
	//	}
	//}
	//return err
}

func SendBatchSms(args ALiYunSendBatchSmsArgs) error {
	client, err := CreateClient()
	if err != nil {
		return err
	}
	sendBatchSmsRequest := &dysmsapi20170525.SendBatchSmsRequest{
		SignNameJson:      tea.String(g.Cfg().GetString("aliyun_sms.signName")),
		TemplateCode:      tea.String(args.TemplateCode),
		PhoneNumberJson:   tea.String(args.PhoneNumbers),
		TemplateParamJson: tea.String(args.TemplateParam),
	}
	tryErr := func() (e error) {
		defer func() {
			if r := tea.Recover(recover()); r != nil {
				e = r
			}
		}()
		// 复制代码运行请自行打印 API 的返回值
		_, err = client.SendBatchSmsWithOptions(sendBatchSmsRequest, &util.RuntimeOptions{})
		if err != nil {
			return err
		}

		return nil
	}()

	if tryErr != nil {
		var error = &tea.SDKError{}
		if _t, ok := tryErr.(*tea.SDKError); ok {
			error = _t
		} else {
			error.Message = tea.String(tryErr.Error())
		}
		// 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
		// 错误 message
		fmt.Println(tea.StringValue(error.Message))
		// 诊断地址
		var data interface{}
		d := json.NewDecoder(strings.NewReader(tea.StringValue(error.Data)))
		d.Decode(&data)
		if m, ok := data.(map[string]interface{}); ok {
			recommend, _ := m["Recommend"]
			fmt.Println(recommend)
		}
		_, err = util.AssertAsString(error.Message)
		if err != nil {
			return err
		}
	}
	return err
}
