package secretNumber

import (
	"fmt"
	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/baseapi/utils/errlist"
	"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
	"git.rosy.net.cn/jx-callback/business/model"
	"git.rosy.net.cn/jx-callback/business/model/dao"
	"git.rosy.net.cn/jx-callback/business/partner"
	"git.rosy.net.cn/jx-callback/globals/api"
	"github.com/alibabacloud-go/dyplsapi-20170525/client"
	"github.com/alibabacloud-go/tea/tea"
	"strings"
)

//查询线上可购号码余量
func QuerySecretNoRemain(city string) (b bool, err error) {
	result, err := api.SecretNumClient.QuerySecretNoRemain(&client.QuerySecretNoRemainRequest{
		SpecId: tea.Int64(1),     //1：虚商号码，即170或171。
		City:   tea.String(city), //城市名
	})
	if err != nil {
		return false, err
	}
	if tea.StringValue(result.Body.Code) != "OK" {
		err = fmt.Errorf(tea.StringValue(result.Body.Message))
		return false, err
	}
	if tea.Int64Value(result.Body.SecretRemainDTO.Amount) > 0 {
		return true, nil
	}
	return false, err
}

//购买号码
func BuySecretNo(ctx *jxcontext.Context, poolKey, city string) (err error) {
	if poolKey == "" {
		return fmt.Errorf("该品牌未建立号码池，请先在阿里云上建立号码池，再联系技术！")
	}
	if b, err := QuerySecretNoRemain(city); err != nil || !b {
		return fmt.Errorf("所选地区【%s】，已经没有号码余量了，请联系阿里的人增加！", city)
	}
	result, err := api.SecretNumClient.BuySecretNo(&client.BuySecretNoRequest{
		PoolKey: tea.String(poolKey),
		SpecId:  tea.Int64(1),
		City:    tea.String(city),
	})
	if err != nil {
		return err
	}
	if tea.StringValue(result.Body.Code) != "OK" {
		err = fmt.Errorf(tea.StringValue(result.Body.Message))
		return err
	}
	if secretNo := tea.StringValue(result.Body.SecretBuyInfoDTO.SecretNo); secretNo != "" {
		secretNumber := &model.SecretNumber{
			City:    city,
			Number:  secretNo,
			PoolKey: poolKey,
		}
		dao.WrapAddIDCULDEntity(secretNumber, ctx.GetUserName())
		err = dao.CreateEntity(dao.GetDB(), secretNumber)
	}
	return err
}

//绑定号码
func BindAxb(ctx *jxcontext.Context, secretNumber, numberA, numberB, expiration string) (err error) {
	result, err := api.SecretNumClient.BindAxb(&client.BindAxbRequest{
		PhoneNoA:   tea.String(numberA),
		PhoneNoB:   tea.String(numberB),
		PhoneNoX:   tea.String(secretNumber),
		Expiration: tea.String(expiration),
	})
	if err != nil {
		return err
	}
	if tea.StringValue(result.Body.Code) != "OK" {
		err = fmt.Errorf(tea.StringValue(result.Body.Message))
		return err
	}
	return err
}

//查询绑定唯一标识SubsId
func QuerySubsId(poolKey, secretNumber string) (subIDs string, err error) {
	result, err := api.SecretNumClient.QuerySubsId(&client.QuerySubsIdRequest{
		PoolKey:  tea.String(poolKey),
		PhoneNoX: tea.String(secretNumber),
	})
	if err != nil {
		return "", err
	}
	if tea.StringValue(result.Body.Code) != "OK" {
		err = fmt.Errorf(tea.StringValue(result.Body.Message))
		return "", err
	}
	//多个绑定关系是返回的逗号间隔的
	if tea.StringValue(result.Body.SubsId) != "" {
		return *result.Body.SubsId, nil
	}
	return "", err
}

type QuerySubscriptionDetailResult struct {
	Status     int    `json:"status"` //该绑定关系的状态。其中：0：已失效。1：生效中。
	NumberA    string `json:"numberA"`
	NumberB    string `json:"numberB"`
	NumberX    string `json:"numberX"`
	GmtCreate  string `json:"gmtCreate"`  //绑定时间
	ExpireDate string `json:"expireDate"` //绑定过期时间
	SubsID     string `json:"subsID"`     //绑定ID
	PoolKey    string `json:"poolKey"`
}

//查询号码的绑定关系
func QuerySubscriptionDetail(poolKey, phoneNoX string) (querySubscriptionDetailResult []*QuerySubscriptionDetailResult, err error) {
	subIDs, err := QuerySubsId(poolKey, phoneNoX)
	if err != nil {
		return querySubscriptionDetailResult, fmt.Errorf("查询号码绑定关系ID错误！err: %v", err)
	}
	errList := errlist.New()
	for _, v := range strings.Split(subIDs, ",") {
		result, err2 := api.SecretNumClient.QuerySubscriptionDetail(&client.QuerySubscriptionDetailRequest{
			PoolKey:  tea.String(poolKey),
			SubsId:   tea.String(v),
			PhoneNoX: tea.String(phoneNoX),
		})
		if err2 != nil {
			errList.AddErr(err2)
			continue
		}
		if tea.StringValue(result.Body.Code) != "OK" {
			errList.AddErr(fmt.Errorf(tea.StringValue(result.Body.Message)))
			continue
		}
		dto := result.Body.SecretBindDetailDTO
		r := &QuerySubscriptionDetailResult{
			Status:     int(tea.Int64Value(dto.Status)),
			NumberA:    tea.StringValue(dto.PhoneNoA),
			NumberB:    tea.StringValue(dto.PhoneNoB),
			NumberX:    tea.StringValue(dto.PhoneNoX),
			GmtCreate:  tea.StringValue(dto.GmtCreate),
			ExpireDate: tea.StringValue(dto.ExpireDate),
			SubsID:     v,
			PoolKey:    poolKey,
		}
		querySubscriptionDetailResult = append(querySubscriptionDetailResult, r)
	}
	return querySubscriptionDetailResult, err
}

//查询号码的绑定关系2
func QuerySubscriptionDetail2(poolKey, subsId, phoneNoX string) (querySubscriptionDetailResult *QuerySubscriptionDetailResult, err error) {
	result, err2 := api.SecretNumClient.QuerySubscriptionDetail(&client.QuerySubscriptionDetailRequest{
		PoolKey:  tea.String(poolKey),
		SubsId:   tea.String(subsId),
		PhoneNoX: tea.String(phoneNoX),
	})
	if err2 != nil {
		return nil, err2
	}
	if tea.StringValue(result.Body.Code) != "OK" {
		err = fmt.Errorf(tea.StringValue(result.Body.Message))
	}
	dto := result.Body.SecretBindDetailDTO
	r := &QuerySubscriptionDetailResult{
		Status:     int(tea.Int64Value(dto.Status)),
		NumberA:    tea.StringValue(dto.PhoneNoA),
		NumberB:    tea.StringValue(dto.PhoneNoB),
		NumberX:    tea.StringValue(dto.PhoneNoX),
		GmtCreate:  tea.StringValue(dto.GmtCreate),
		ExpireDate: tea.StringValue(dto.ExpireDate),
		SubsID:     subsId,
		PoolKey:    poolKey,
	}
	return r, err
}

//修改绑定关系
//修改哪个字段就传哪个字段
//updateNoA：修改A号码。
//updateNoB：修改B号码。
//updateExpire：修改绑定关系有效期。
func UpdateSubscription(poolKey, subsId, phoneNoX, phoneNoA, phoneNoB, expiration string) (err error) {
	params := &client.UpdateSubscriptionRequest{
		PoolKey:  tea.String(poolKey),
		SubsId:   tea.String(subsId),
		PhoneNoX: tea.String(phoneNoX),
	}
	bindResult, _ := QuerySubscriptionDetail2(poolKey, subsId, phoneNoX)
	if bindResult.NumberA != phoneNoA {
		params.OperateType = tea.String("updateNoA")
		params.PhoneNoA = tea.String(phoneNoA)
	}
	if bindResult.ExpireDate != expiration {
		params.OperateType = tea.String("updateExpire")
		params.Expiration = tea.String(expiration)
	}
	if bindResult.NumberB != phoneNoB {
		params.OperateType = tea.String("updateNoB")
		params.PhoneNoB = tea.String(phoneNoB)
	}
	result, err := api.SecretNumClient.UpdateSubscription(params)
	if err != nil {
		return err
	}
	if tea.StringValue(result.Body.Code) != "OK" {
		err = fmt.Errorf(tea.StringValue(result.Body.Message))
		return err
	}
	return err
}

//解除号码的绑定关系
func UnbindSubscription(poolKey, subsId, phoneNoX string) (err error) {
	result, err := api.SecretNumClient.UnbindSubscription(&client.UnbindSubscriptionRequest{
		PoolKey:  tea.String(poolKey),
		SubsId:   tea.String(subsId),
		SecretNo: tea.String(phoneNoX),
	})
	if err != nil {
		return err
	}
	if tea.StringValue(result.Body.Code) != "OK" {
		err = fmt.Errorf(tea.StringValue(result.Body.Message))
		return err
	}
	return err
}

type SecretNumberMsgRes struct {
	PhoneNo          string `json:"phone_no"`
	PoolKey          string `json:"pool_key"`
	City             string `json:"city"`
	SubID            int64  `json:"sub_id"`
	UnconnectedCause int    `json:"unconnected_cause"`
	CallTime         string `json:"call_time"`
	CallOutTime      string `json:"call_out_time"`
	PeerNo           string `json:"peer_no"`
	CalledDisplayNo  string `json:"called_display_no"`
	ReleaseDir       int    `json:"release_dir"`
	RingTime         string `json:"ring_time"`
	CallID           string `json:"call_id"`
	StartTime        string `json:"start_time"`
	CallStatus       string `json:"call_status"`
	FreeRingTime     string `json:"free_ring_time"`
	PartnerKey       string `json:"partner_key"`
	ControlMsg       string `json:"control_msg"`
	ID               int64  `json:"id"`
	SecretNo         string `json:"secret_no"`
	CallType         int    `json:"call_type"`
	ReleaseCause     int    `json:"release_cause"`
	ControlType      string `json:"control_type"`
	ReleaseTime      string `json:"release_time"`
}

func CallbackBrandBill(res *SecretNumberMsgRes) (err error) {
	var (
		db       = dao.GetDB()
		errLists = errlist.New()
	)
	if brands, _ := dao.GetBrands(db, "", 0, res.PoolKey, false, ""); len(brands) > 0 {
		if brandID := brands[0].ID; brandID != 0 {
			price := utils.Float64TwoInt(utils.Str2Time(res.ReleaseTime).Sub(utils.Str2Time(res.StartTime)).Minutes()+1) * 6
			if err = partner.CurStoreAcctManager.InsertBrandBill(jxcontext.AdminCtx, brandID, price, model.BrandBillTypeExpend, model.BrandBillFeeTypeSecretNumber, "", ""); err == nil {
				//计算余额，小于10就解绑
				balance, _ := partner.CurStoreAcctManager.GetBrandBalance(brandID)
				if balance < model.BrandBalanceLimit {
					//解绑所有的号码关系
					if results, err2 := QuerySubscriptionDetail(res.PoolKey, res.SecretNo); err2 == nil && len(results) > 0 {
						for _, v := range results {
							if err = UnbindSubscription(res.PoolKey, v.SubsID, v.NumberX); err != nil {
								errLists.AddErr(err)
							}
						}
					}
				}
			}
		}
	}
	err = errLists.GetErrListAsOne()
	return err
}

func GetBrandSecretNumbers(ctx *jxcontext.Context, brandID int) (results []*model.SecretNumber, err error) {
	return dao.GetBrandSecretNumbers(dao.GetDB(), brandID)
}
