package service

import (
	"context"
	"encoding/json"
	v1 "voucher/api/v1"
	"voucher/internal/biz/bo"
	"voucher/internal/biz/businesserr"
	"voucher/internal/biz/vo"
)

func (c *CmbService) Order(ctx context.Context, request *v1.CmbRequest) (*v1.CmbReply, error) {

	order, product, err := c.order(ctx, request)

	if err != nil {
		return c.OrderFail(ctx, order, product, err)
	}

	return c.OrderSuccess(ctx, order.OrderNo)
}

func (c *CmbService) order(ctx context.Context, request *v1.CmbRequest) (*bo.OrderBo, *bo.ProductBo, error) {

	bizContent, err := c.CmbMixRepo.OrderVerify(ctx, request)
	if err != nil {
		return nil, nil, err
	}

	boReq := &bo.OrderCreateReqBo{
		OutBizNo:    bizContent.TransactionId,
		ProductNo:   bizContent.ActivityId,
		Account:     bizContent.CmbUid,
		AppID:       bizContent.AppId,
		Attach:      bizContent.Attach,
		AccountType: vo.OrderAccountTypeOpenId,
		Type:        vo.OrderTypeCmb,
		NotifyUrl:   c.bc.Cmb.NotifyUrl,
	}

	order, product, err := c.VoucherBiz.CmbOrder(ctx, boReq)
	if err != nil {
		return nil, nil, err
	}

	return order, product, nil
}

func (c *CmbService) OrderSuccess(ctx context.Context, orderNo string) (*v1.CmbReply, error) {

	bizReply := &v1.CmbOrderReply{
		RespCode: vo.CmbResponseStatusSuccess.GetValue(),
		RespMsg:  "成功",
		CodeNo:   orderNo,
	}

	replyBizContent, _ := json.Marshal(bizReply)

	return c.GetResponse(ctx, replyBizContent)
}

func (c *CmbService) OrderFail(ctx context.Context, order *bo.OrderBo, product *bo.ProductBo, err error) (*v1.CmbReply, error) {

	bizReply := &v1.CmbOrderReply{}

	if e, ok := err.(*businesserr.BusinessErr); ok {

		isMultiErr := false

		if product != nil && product.ActivityId != "" {
			isMultiErr = true
		} else if order != nil && order.ActivityId != "" {
			isMultiErr = true
		}

		if isMultiErr {
			cmbAPIError := e.HandleMULTIThirdErrCode()
			bizReply = &v1.CmbOrderReply{
				RespCode:     vo.CmbResponseStatusFail.GetValue(),
				RespMsg:      cmbAPIError.Description,
				CodeNo:       "",
				ThirdErrCode: string(cmbAPIError.ThirdErrCode),
			}
		} else {
			cmbAPIError := e.HandleThirdErrCode()
			bizReply = &v1.CmbOrderReply{
				RespCode:     vo.CmbResponseStatusFail.GetValue(),
				RespMsg:      cmbAPIError.Description,
				CodeNo:       "",
				ThirdErrCode: string(cmbAPIError.ThirdErrCode),
			}
		}

	} else {
		bizReply = &v1.CmbOrderReply{
			RespCode:     vo.CmbResponseStatusFail.GetValue(),
			RespMsg:      err.Error(),
			CodeNo:       "",
			ThirdErrCode: string(businesserr.ThirdErrCodeDefault),
		}
	}

	replyBizContent, _ := json.Marshal(bizReply)

	return c.GetResponse(ctx, replyBizContent)
}
