package cmb

import (
	"context"
	"encoding/json"
	"fmt"
	"time"
	v1 "voucher/api/v1"
	"voucher/internal/biz/bo"
	"voucher/internal/biz/vo"
	"voucher/internal/pkg/uid"
)

func (v *Cmb) OrderConsume(ctx context.Context, order *bo.OrderBo) (outRequestNo string, err error) {

	if order.Status.IsWait() {
		return outRequestNo, fmt.Errorf("订单状态错误,%s", order.Status.GetText())
	}

	if !order.Channel.IsWeChat() {
		return outRequestNo, fmt.Errorf("订单渠道错误,%s", order.Channel.GetText())
	}

	if err = v.ing(ctx, order.ID); err != nil {
		return
	}

	orderWechat, err := v.create(ctx, order)
	if err != nil {
		return
	}

	// todo
	// 注册“刚哥那边”回调中心tag,一个批次只能注册一个tag，微信立减金消费时根据不同的tag消费(区分测试/正式注册tag

	couponId, err := v.WechatCpnRepo.Order(ctx, orderWechat)
	if err != nil {
		return outRequestNo, v.fail(ctx, order, orderWechat, err.Error())
	}

	if err = v.success(ctx, order, orderWechat, couponId); err != nil {
		return
	}

	return orderWechat.OutRequestNo, err
}

func (v *Cmb) create(ctx context.Context, order *bo.OrderBo) (*bo.OrderWechatBo, error) {
	outRequestNo, err := v.GenerateMixRepo.GeneratorString(ctx, uid.OrderWechat)
	if err != nil {
		return nil, err
	}

	req := &bo.OrderWechatBo{
		OrderNo:           order.OrderNo,
		OutRequestNo:      outRequestNo,
		AppID:             order.AppID,
		StockCreatorMchid: order.MerchantNo,
		OpenID:            order.Account,
		StockID:           order.BatchNo,
		Status:            vo.OrderWechatStatusWait,
	}

	orderWechat, err := v.OrderWechatRepo.Create(ctx, req)
	if err != nil {
		return nil, err
	}

	return orderWechat, nil
}

func (v *Cmb) ing(ctx context.Context, id uint64) error {

	return v.OrderRepo.Ing(ctx, id)
}

func (v *Cmb) success(ctx context.Context, order *bo.OrderBo, orderWechat *bo.OrderWechatBo, couponId string) error {

	if err := v.OrderWechatRepo.Success(ctx, orderWechat.ID, couponId); err != nil {
		return err
	}

	return v.OrderRepo.Success(ctx, order.ID)
}

func (v *Cmb) fail(ctx context.Context, order *bo.OrderBo, orderWechat *bo.OrderWechatBo, remarks string) error {

	if err := v.OrderWechatRepo.Fail(ctx, orderWechat.ID, remarks); err != nil {
		return err
	}

	return v.OrderRepo.Fail(ctx, order.ID)
}

func (v *Cmb) NotifyConsume(ctx context.Context, order *bo.OrderBo, orderOutRequestNo string) error {

	orderWechat, err := v.OrderWechatRepo.GetByOutRequestNo(ctx, orderOutRequestNo)
	if err != nil {
		return err
	}

	if !orderWechat.Status.CanNotify() {
		return fmt.Errorf("微信订单状态错误,不能通知:%s", order.Status.GetText())
	}

	status, err := orderWechat.Status.GetCmbStatusText()
	if err != nil {
		return err
	}
	req := &v1.CmbNotifyRequest{
		Ticket:    orderWechat.OrderNo,
		Status:    status.GetValue(),
		TransDate: time.Now().Format("20060102150405"),
		OrgNo:     v.bc.Cmb.OrgNo,
		Ext:       "",
	}
	bizJsonBytes, err := json.Marshal(req)
	if err != nil {
		return err
	}

	request, err := v.CmbMixRepo.GetRequest(ctx, &bo.CmbRequestBo{
		FuncName:   vo.CmbNotifyFuncName,
		BizContent: string(bizJsonBytes),
	})
	if err != nil {
		return err
	}

	requestBytes, err := json.Marshal(request)
	if err != nil {
		return err
	}

	orderNotify, err := v.OrderNotifyRepo.Create(ctx, &bo.OrderNotifyBo{
		OrderNo:      order.OrderNo,
		OutRequestNo: orderWechat.OutRequestNo,
		Request:      string(requestBytes),
		NotifyUrl:    order.NotifyUrl,
	})
	if err != nil {
		return err
	}

	// todo 发起请求
	fmt.Print(orderNotify)

	return nil
}

func (v *Cmb) notifySuccess(ctx context.Context, id uint64) error {
	return v.OrderNotifyRepo.Success(ctx, id, "")
}

func (v *Cmb) notifyFail(ctx context.Context, id uint64, remark string) error {
	return v.OrderNotifyRepo.Fail(ctx, id, remark)
}
