package walmart

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

	"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/net/gtrace"
	"github.com/gogf/gf/v2/os/glog"
	"github.com/gogf/gf/v2/text/gstr"
	"github.com/gogf/gf/v2/util/gconv"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/trace"
)

func (w *Client) BindCard(ctx context.Context, input *redeem.CommonSendCardReq) (result *redeem.BindCardOutput, err error) {
	ctx, span := gtrace.NewSpan(ctx, "携程绑卡", trace.WithTimestamp(time.Now()), trace.WithAttributes(
		attribute.String("category", gconv.String(consts.CardRedeemAccountCategoryWalMart)),
		attribute.String("data", gconv.String(input)),
	),
	)
	defer span.End()
	glog.Info(ctx, "携程绑卡请求", g.Map{
		"ck":        input.Cookie,
		"card_num":  input.CardNo,
		"card_pwd":  input.GiftCardPwd,
		"order_num": input.OrderNo,
		"money":     input.OrderAmount,
	})
	resp := gclient.New().SetTimeout(30*time.Second).PostBytes(ctx, fmt.Sprintf("http://ctrip:5001/xiecheng/v3/card/bind"), gjson.MustEncode(g.Map{
		"ck":        input.Cookie,
		"card_num":  input.CardNo,
		"card_pwd":  input.GiftCardPwd,
		"order_num": input.OrderNo,
		"money":     input.OrderAmount,
	}))
	respStr := utils.UnicodeToZh(gconv.String(resp))
	type bindCardResp struct {
		Code BindCardType `json:"code"`
		Msg  string       `json:"msg"`
	}
	glog.Info(ctx, "携程绑卡返回", respStr)
	var respSt bindCardResp
	err = gjson.DecodeTo(respStr, &respSt)
	result = &redeem.BindCardOutput{
		RawData: utils.UnicodeToZh(gconv.String(respSt)),
		Amount:  input.OrderAmount,
		Status:  respSt.Code.Status(),
		Remarks: respSt.Msg,
	}
	return
}

// QueryBalance 查询余额
// FIXME: 查询余额接口目前不可用
func (w *Client) QueryBalance(ctx context.Context, input *redeem.QueryBalanceReq) (result *redeem.QueryBalanceRes, err error) {
	//client := gclient.New()
	//jdCfg := config.NewConfig(ctx).GetJDCardCfg()
	//resp := client.PostBytes(ctx, fmt.Sprintf("%s/walmart/account/balance/query", jdCfg.Url), gjson.MustEncode(g.Map{
	//	"cookie": input.Cookie,
	//}))
	//var respSt BalanceResp
	//err = gjson.DecodeTo(resp, &respSt)
	//result = &redeem.QueryBalanceRes{
	//	Ck:    input.Cookie,
	//	Money: gconv.Float64(respSt.Data.Balance),
	//	Ok:    respSt.Status,
	//}
	return &redeem.QueryBalanceRes{
		Ck:    input.Cookie,
		Money: 0,
		Ok:    true,
	}, nil
}

// QueryBalanceWithCache FIXME: 查询余额接口目前不可用
func (w *Client) QueryBalanceWithCache(ctx context.Context, input *redeem.QueryBalanceReq, duration time.Duration) (result *redeem.QueryBalanceRes, err error) {
	newCache, err := cache.NewCache().Get(ctx, cache.PrefixWalmartAccountQueryBalanceWithCookie.Key(input.Cookie))
	if err == nil && newCache != nil && !newCache.IsNil() {
		err = newCache.Scan(&result)
		return
	}
	result, err = w.QueryBalance(ctx, input)
	_, err = cache.NewCache().SetIfNotExist(ctx, cache.PrefixWalmartAccountQueryBalanceWithCookie.Key(input.Cookie), result, duration)
	return
}

func (w *Client) QueryUserInfoWithCache(ctx context.Context, cookie string, duration time.Duration) (result *redeem.QueryUserInfoRes, err error) {
	return &redeem.QueryUserInfoRes{
		NickName: "",
		Username: "",
		Ok:       true,
	}, nil
}

func (w *Client) QueryUserInfo(ctx context.Context, cookie string) (result *redeem.QueryUserInfoRes, err error) {
	return &redeem.QueryUserInfoRes{
		NickName: "",
		Username: "",
		Ok:       true,
	}, nil
}

func (w *Client) QueryCard(ctx context.Context, input *redeem.CommonSendCardReq) (result *redeem.BindCardOutput, err error) {
	jdCfg := config.NewConfig(ctx).GetJDCardCfg()
	client := gclient.New()
	client.SetTimeout(30 * time.Second)
	resp := client.PostBytes(ctx, fmt.Sprintf("%s/walmart/api/v2/walmart/card/query", jdCfg.Url), gjson.MustEncode(g.Map{
		"card_num": input.CardNo,
	}))
	var respSt QueryCardResp
	err = gjson.DecodeTo(resp, &respSt)
	result = &redeem.BindCardOutput{
		RawData: gconv.String(respSt),
		Amount:  gconv.Float64(respSt.Data.Money),
		Status:  consts.RedeemOrderSuccess,
	}
	return
}

func (w *Client) CheckCard(ctx context.Context, input *redeem.CommonCardTrimAndCheckerInput) (output *redeem.CommonCardTrimAndCheckerOutput) {
	output = &redeem.CommonCardTrimAndCheckerOutput{
		IsOk: true,
		CommonCardTrimAndCheckerInput: &redeem.CommonCardTrimAndCheckerInput{
			CardNo:      gstr.TrimAll(input.CardNo),
			GiftCardPwd: gstr.TrimAll(input.GiftCardPwd),
		},
	}
	return
}

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