package biz

import (
	"context"
	"fmt"
	"github.com/wechatpay-apiv3/wechatpay-go/services/cashcoupons"
	"time"
	v1 "voucher/api/v1"
	"voucher/internal/biz/do"
	"voucher/internal/biz/vo"
	"voucher/internal/pkg/lock"
)

func (this *VoucherBiz) CmbProductQuery(ctx context.Context, productNo string) (reps *v1.CmbQueryProductReply, err error) {

	c := vo.CmbProductQueryLockKey.BuildCache([]string{productNo})

	err = lock.NewMutex(this.rdb.Rdb, c.TTL).Lock(ctx, c.Key, func(ctx context.Context) error {

		product, err3 := this.ProductRepo.GetByProductNo(ctx, productNo)
		if err3 != nil {
			return err3
		}

		if !product.Channel.IsWeChat() {
			return fmt.Errorf("只支持微信")
		}

		wechatResp, err4 := this.WechatCpnRepo.QueryProduct(ctx, product.MchId, product.BatchNo)
		if err4 != nil {
			return err4
		}

		reps = &v1.CmbQueryProductReply{
			RespCode:       vo.CmbResponseStatusSuccess.GetValue(),
			RespMsg:        "成功",
			ActivityName:   product.Name,
			ActivityId:     product.ProductNo,
			Amount:         "",
			MinAmount:      "",
			AvailableType:  "",
			AvailableDays:  "", // 动态有效期天数
			StartTime:      "",
			EndTime:        "",
			AvailableStock: "",
			Detail:         *wechatResp.Description,
		}

		inputFormat := time.RFC3339

		if wechatResp.AvailableBeginTime != nil {

			availableBeginTime, _ := time.Parse(inputFormat, *wechatResp.AvailableBeginTime)
			reps.StartTime = availableBeginTime.Format("2006-01-02 15:04:05.000")
			reps.SaleStartTime = reps.StartTime
		}

		if wechatResp.AvailableEndTime != nil {
			availableEndTime, _ := time.Parse(inputFormat, *wechatResp.AvailableEndTime)
			reps.EndTime = availableEndTime.Format("2006-01-02 15:04:05.000")
			reps.SaleEndTime = reps.EndTime
		}

		reps.Amount = fmt.Sprintf("%d", *wechatResp.StockUseRule.FixedNormalCoupon.CouponAmount)
		reps.MinAmount = fmt.Sprintf("%d", *wechatResp.StockUseRule.FixedNormalCoupon.TransactionMinimum)

		availableStock := *wechatResp.StockUseRule.MaxCoupons - *wechatResp.DistributedCoupons
		reps.AvailableStock = fmt.Sprintf("%d", availableStock)

		availableType, err3 := product.AvailableType.GetCmbAvailableType()
		if err3 != nil {
			return err3
		}

		reps.AvailableType = availableType.GetValue()
		reps.AvailableDays = fmt.Sprintf("%d", product.AvailableDays)

		return nil
	})

	return
}

func (this *VoucherBiz) WxResp(wxResp *cashcoupons.Stock) (reps *do.WxResp) {

	availableStock := *wxResp.StockUseRule.MaxCoupons - *wxResp.DistributedCoupons
	couponAmount := *wxResp.StockUseRule.FixedNormalCoupon.CouponAmount / 100

	remainingBudget := availableStock * couponAmount

	stockUsageRate := float64(*wxResp.DistributedCoupons) / float64(*wxResp.StockUseRule.MaxCoupons) * 100

	req := &do.WxResp{
		Amount:          couponAmount,
		AllBudget:       *wxResp.StockUseRule.MaxAmount / 100,
		AllStock:        *wxResp.StockUseRule.MaxCoupons,
		UsedStock:       *wxResp.DistributedCoupons,
		UsedBudget:      *wxResp.DistributedCoupons * couponAmount,
		AvailableStock:  availableStock,
		AvailableBudget: remainingBudget,
		StockUsageRate:  stockUsageRate,
	}

	inputFormat := time.RFC3339

	if wxResp.AvailableBeginTime != nil {
		availableBeginTime, _ := time.Parse(inputFormat, *wxResp.AvailableBeginTime)
		req.StartTime = &availableBeginTime
	}

	if wxResp.AvailableEndTime != nil {
		availableEndTime, _ := time.Parse(inputFormat, *wxResp.AvailableEndTime)
		req.EndTime = &availableEndTime
	}

	return req
}
