package redeem

import (
	"context"
	"fmt"
	"kami/utility/cache"
	"kami/utility/config"
	"kami/utility/integration/redeem"
	"time"

	list "github.com/duke-git/lancet/v2/datastructure/list"
	"github.com/duke-git/lancet/v2/strutil"
	"github.com/gogf/gf/v2/encoding/gjson"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/gclient"
	"github.com/gogf/gf/v2/os/glog"
	"github.com/gogf/gf/v2/text/gstr"
	"github.com/gogf/gf/v2/util/gconv"
)

func (c *Client) BindCard(ctx context.Context, input *redeem.CommonSendCardReq) (result *redeem.BindCardOutput, err error) {
	//过滤充值卡
	body, _ := gjson.Encode(g.Map{
		"cookies":                   input.Cookie,
		"order_num":                 input.OrderNo,
		"card_pwd":                  input.GiftCardPwd,
		"order_amount":              input.OrderAmount,
		"is_different_amount_allow": input.IsAllowDifferentAmount,
	})
	jdCfg := config.NewConfig(ctx).GetJDCardCfg()
	client := gclient.New()
	client.SetTimeout(30 * time.Second)
	response := client.PostBytes(ctx, fmt.Sprintf("%s/jd/card/bind", jdCfg.Url), body)
	glog.Info(ctx, "充值接口返回结果", response)
	resResult := new(ServiceOneCommonResponse)
	err = gjson.DecodeTo(response, &resResult)
	result = resResult.MapResult(gconv.String(response))
	result.RawData = gconv.String(response)
	result.GiftCardId = resResult.Data.Data.GiftCardId
	result.CardTypeName = resResult.Data.Data.CardTypeName
	return
}

// QueryBalance 查询用户余额
func (c *Client) QueryBalance(ctx context.Context, input *redeem.QueryBalanceReq) (result *redeem.QueryBalanceRes, err error) {
	//过滤充值卡
	body, _ := gjson.Encode(g.List{
		g.Map{
			"ck": input.Cookie,
		},
	})
	jdCfg := config.NewConfig(ctx).GetJDCardCfg()
	client := gclient.New()
	client.SetTimeout(30 * time.Second)
	response := client.PostBytes(ctx, fmt.Sprintf("%s/jd/money/check", jdCfg.Url), body)
	glog.Info(ctx, "余额查询接口返回结果", response)
	resResult := make([]*QueryBalanceInfo, 0)
	err = gjson.DecodeTo(response, &resResult)
	if len(resResult) > 0 {
		result = &redeem.QueryBalanceRes{
			Ck:    resResult[0].Ck,
			Money: resResult[0].Money,
		}
		return
	}
	return
}

func (c *Client) QueryBalanceWithCache(ctx context.Context, input *redeem.QueryBalanceReq, duration time.Duration) (result *redeem.QueryBalanceRes, err error) {
	newCache, err := cache.NewCache().Get(ctx, cache.PrefixJDAccountQueryBalanceWithCookie.Key(input.Cookie))
	if err == nil && newCache != nil && !newCache.IsNil() {
		err = newCache.Scan(&result)
		return
	}
	result, err = c.QueryBalance(ctx, input)
	_, err = cache.NewCache().SetIfNotExist(ctx, cache.PrefixJDAccountQueryBalanceWithCookie.Key(input.Cookie), result, duration)
	return
}

func (c *Client) QueryUserInfo(ctx context.Context, cookie string) (result *redeem.QueryUserInfoRes, err error) {
	//过滤充值卡
	body, _ := gjson.Encode(g.Map{
		"cookie": cookie,
	})
	result = &redeem.QueryUserInfoRes{
		Ok: false,
	}
	client := gclient.New()
	client.SetTimeout(30 * time.Second)
	response := client.PostBytes(ctx, fmt.Sprintf("%s/jd/user/info", config.NewConfig(ctx).GetJDCardCfg().Url), body)
	resResult := CommonResponse[QueryUserInfo]{}
	err = gjson.DecodeTo(response, &resResult)
	if resResult.Code == 100 {
		result.Username = resResult.Data.Username
		result.NickName = resResult.Data.NickName
		result.Ok = true
	}
	return
}

func (c *Client) QueryUserInfoWithCache(ctx context.Context, cookie string, duration time.Duration) (result *redeem.QueryUserInfoRes, err error) {
	newCache, err := cache.NewCache().Get(ctx, cache.PrefixJDAccountQueryCache.Key(cookie))
	if err == nil && newCache != nil && !newCache.IsNil() {
		err = newCache.Scan(&result)
		return
	}
	result, err = c.QueryUserInfo(ctx, cookie)
	_, err = cache.NewCache().SetIfNotExist(ctx, cache.PrefixJDAccountQueryCache.Key(cookie), result, duration)
	return
}

func (c *Client) QueryCard(ctx context.Context, input *redeem.CommonSendCardReq) (result *redeem.BindCardOutput, err error) {
	//过滤充值卡
	body, _ := gjson.Encode(g.Map{
		"cookies":                   input.Cookie,
		"order_num":                 input.OrderNo,
		"card_pwd":                  input.GiftCardPwd,
		"order_amount":              input.OrderAmount,
		"is_different_amount_allow": input.IsAllowDifferentAmount,
	})
	jdCfg := config.NewConfig(ctx).GetJDCardCfg()
	client := gclient.New()
	client.SetTimeout(30 * time.Second)
	response := client.PostBytes(ctx, fmt.Sprintf("%s/jd/card/check", jdCfg.Url), body)
	glog.Info(ctx, "充值接口返回结果", response)
	resResult := new(ServiceOneCommonResponse)
	err = gjson.DecodeTo(response, &resResult)
	result = resResult.MapResult(gconv.String(response))
	result.RawData = gconv.String(response)
	return
}

func (c *Client) CheckCard(ctx context.Context, input *redeem.CommonCardTrimAndCheckerInput) (output *redeem.CommonCardTrimAndCheckerOutput) {
	//	判断当前卡号是否存在连字号
	output = &redeem.CommonCardTrimAndCheckerOutput{
		IsOk: false,
	}
	input.GiftCardPwd = gstr.ToUpper(input.GiftCardPwd)
	if gstr.Contains(input.GiftCardPwd, "-") {
		result := list.NewList(strutil.SplitAndTrim(input.GiftCardPwd, "-", " "))
		if result.Size() != 4 {
			return
		}
		iter := result.Iterator()
		for iter.HasNext() {
			item, _ := iter.Next()
			if gstr.LenRune(item) != 4 {
				return
			}
		}
		output.IsOk = true
		return
	}
	if gstr.LenRune(input.GiftCardPwd) != 16 {
		output.IsOk = false
		return
	}
	//	以4个为一组，添加-
	input.GiftCardPwd = gstr.ChunkSplit(input.GiftCardPwd, 4, "-")
	output = &redeem.CommonCardTrimAndCheckerOutput{
		IsOk:                          true,
		CommonCardTrimAndCheckerInput: input,
	}
	return
}

// CheckAllowedAmount 规则
func (c *Client) CheckAllowedAmount(ctx context.Context, amount float64) bool {
	return true
}
