package services

import (
	"encoding/json"
	"eta/eta_mobile/models"
	"eta/eta_mobile/utils"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
)

// NanHuaSms 南华短信服务
type NanHuaSms struct{}

func (cli *NanHuaSms) SendUserLoginCode(req UserLoginSmsCodeReq) (result UserLoginSmsCodeResult, err error) {
	// 短信内容
	confMap, e := models.GetBusinessConf()
	if e != nil {
		err = fmt.Errorf("GetBusinessConf err: %s", e.Error())
		return
	}
	tpl := confMap[models.BusinessConfLoginSmsTplContent]
	if tpl == "" {
		err = fmt.Errorf("短信模板有误")
		return
	}
	smsContent := strings.Replace(tpl, "{{VERIFY_CODE}}", req.VerifyCode, 1)
	smsContent = strings.Replace(smsContent, "{{EXPIRED_MINUTE}}", strconv.Itoa(utils.VerifyCodeExpireMinute), 1)

	var params NanHuaSmsApiParams
	var mobileRequest NanHuaSmsApiRequest
	mobileRequest.Mobile = req.Mobile
	params.ApiHost = confMap[models.BusinessConfNanHuaSmsApiHost]
	params.AppKey = confMap[models.BusinessConfNanHuaSmsAppKey]
	params.AppSecret = confMap[models.BusinessConfNanHuaSmsAppSecret]
	params.Content = smsContent
	params.TypeCode = 1
	params.Requests = append(params.Requests, mobileRequest)

	// 请求接口
	res, e := CurlNanHuaSmsApi(params)
	if e != nil {
		err = fmt.Errorf("CurlNanHuaSmsApi err: %s", e.Error())
		return
	}
	result.Success = res.Success
	result.Message = res.Message
	if len(res.Data.SmsResponses) > 0 {
		result.RequestId = res.Data.SmsResponses[0].RecId
	}
	return
}

// NanHuaSmsApiParams 南华短信接口请求参数
type NanHuaSmsApiParams struct {
	ApiHost   string                `json:"-" description:"api-host"`
	AppKey    string                `json:"-" description:"app-key"`
	AppSecret string                `json:"-" description:"app-secret"`
	Content   string                `json:"content" description:"短信内容，必填"`
	Username  string                `json:"username" description:"使用人南华域账号，非必填"`
	TypeCode  int                   `json:"typeCode" description:"1-普通短信；2-营销短信"`
	Requests  []NanHuaSmsApiRequest `json:"requests" description:"手机号、内容信息"`
}

// NanHuaSmsApiRequest 南华短信接口请求-手机号信息
type NanHuaSmsApiRequest struct {
	Content        string `json:"content" description:"短信内容，非必填，填写则该手机号使用此内容单独发送"`
	Mobile         string `json:"mobile" description:"手机号，必填"`
	OrgId          string `json:"orgId" description:"客户所属ctp机构ID，非必填，用来计费（建议填写）"`
	OaDepartmentId string `json:"oaDepartmentId" description:"客户所属oa部门ID，非必填，用来计费"`
}

// NanHuaSmsApiResult 南华短信接口-响应体
type NanHuaSmsApiResult struct {
	ErrorCode int    `json:"errorcode" description:"状态码：0-成功；400-失败"`
	Success   bool   `json:"success" description:"true-成功；false-失败"`
	Message   string `json:"message" description:"请求失败提示"`
	Data      struct {
		SmsResponses []struct {
			Mobile string `json:"mobile" description:"手机号"`
			RecId  string `json:"recId" description:"短信id，用来回查发送状态"`
		} `json:"smsResponses"`
	} `json:"data"`
}

// CurlNanHuaSmsApi 请求南华短信接口
func CurlNanHuaSmsApi(params NanHuaSmsApiParams) (result NanHuaSmsApiResult, err error) {
	url := fmt.Sprint(params.ApiHost)
	byteParams, e := json.Marshal(params)
	if e != nil {
		err = fmt.Errorf("data json marshal err: %s", e.Error())
		return
	}

	body := ioutil.NopCloser(strings.NewReader(string(byteParams)))
	client := &http.Client{}
	req, e := http.NewRequest("POST", url, body)
	if e != nil {
		err = fmt.Errorf("http create request err: %s", e.Error())
		return
	}

	contentType := "application/json;charset=utf-8"
	req.Header.Set("Content-Type", contentType)
	req.Header.Set("App-Key", params.AppKey)
	req.Header.Set("App-Secret", params.AppSecret)
	resp, e := client.Do(req)
	if e != nil {
		err = fmt.Errorf("http client do err: %s", e.Error())
		return
	}
	defer func() {
		_ = resp.Body.Close()
	}()
	b, e := ioutil.ReadAll(resp.Body)
	if e != nil {
		err = fmt.Errorf("resp body read err: %s", e.Error())
		return
	}
	if len(b) == 0 {
		err = fmt.Errorf("resp body is empty")
		return
	}
	if e = json.Unmarshal(b, &result); e != nil {
		err = fmt.Errorf("result unmarshal err: %s\nresult: %s", e.Error(), string(b))
		return
	}
	return
}
