package logic

import (
	"errors"
	"fusenapi/model/gmodel"
	"fusenapi/utils/auth"
	"fusenapi/utils/basic"
	"time"

	"context"

	"fusenapi/server/home-user-auth/internal/svc"
	"fusenapi/server/home-user-auth/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
	"gorm.io/gorm"
)

type UserAgainOrderLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUserAgainOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserAgainOrderLogic {
	return &UserAgainOrderLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

// 处理进入前逻辑w,r
// func (l *UserAgainOrderLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
// }

// 处理逻辑后 w,r 如:重定向, resp 必须重新处理
// func (l *UserAgainOrderLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) {
// // httpx.OkJsonCtx(r.Context(), w, resp)
// }

func (l *UserAgainOrderLogic) UserAgainOrder(req *types.UserAgainOrderReq, userinfo *auth.UserInfo) (resp *basic.Response) {
	// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
	// userinfo 传入值时, 一定不为null
	if userinfo == nil || userinfo.UserId == 0 {
		return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found")
	}

	// 查询订单数据
	orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn)
	orderDetailTemplateModel := gmodel.NewFsOrderDetailTemplateModel(l.svcCtx.MysqlConn)
	fsOrderDetailModel := gmodel.NewFsOrderDetailModel(l.svcCtx.MysqlConn)
	fsProductDesignModel := gmodel.NewFsProductDesignModel(l.svcCtx.MysqlConn)

	rsbOrder := orderModel.RowSelectBuilder(nil)
	rsbOrder = rsbOrder.Where("sn =?", req.Sn).Preload("FsOrderDetails")
	rsbOrder = rsbOrder.Preload("FsOrderDetails", func(dbPreload *gorm.DB) *gorm.DB {
		return dbPreload.Table(fsOrderDetailModel.TableName()).Preload("FsOrderDetailTemplateInfo", func(dbPreload *gorm.DB) *gorm.DB {
			return dbPreload.Table(orderDetailTemplateModel.TableName()).Preload("FsProductDesignInfo", func(dbPreload *gorm.DB) *gorm.DB {
				return dbPreload.Table(fsProductDesignModel.TableName())
			})
		})
	})

	fsOrderRelInfo, err := orderModel.FindOneByQuery(l.ctx, rsbOrder, nil)

	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return resp.SetStatusWithMessage(basic.CodeDbRecordNotFoundErr, "order not found")
		}
		logx.Error(err)
		return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to get order info")
	}

	if len(fsOrderRelInfo.FsOrderDetails) > 0 {
		for _, fsOrderDetail := range fsOrderRelInfo.FsOrderDetails {
			var isCheck int64 = 1
			productDesignInfo := fsOrderDetail.FsOrderDetailTemplateInfo.FsProductDesignInfo
			if productDesignInfo.Id != 0 {

				// 查找是否有此材质、产品、大小id的阶梯价格
				productPriceModel := gmodel.NewFsProductPriceModel(l.svcCtx.MysqlConn)
				priceStatus := int64(1)
				priceReq := gmodel.FindOneProductPriceByParamsReq{
					ProductId:  productDesignInfo.ProductId,
					MaterialId: productDesignInfo.MaterialId,
					SizeId:     productDesignInfo.SizeId,
					Status:     &priceStatus,
				}
				productPriceInfo, err := productPriceModel.FindOneProductPriceByParams(l.ctx, priceReq)
				if err == nil && productPriceInfo.Id != 0 && *productPriceInfo.EachBoxNum > 0 {

					// 买的数量和每箱数量取余为0 且 份数大于等于最小购买数量才算满足条件
					if *fsOrderDetail.BuyNum%*productPriceInfo.EachBoxNum == 0 && int64(float64(*fsOrderDetail.BuyNum)/float64(*productPriceInfo.EachBoxNum)) >= *productPriceInfo.MinBuyNum {

						// 查询购物车
						cartModel := gmodel.NewFsCartModel(l.svcCtx.MysqlConn)
						cartStatus := int64(1)
						cartReq := gmodel.FindOneCartByParamsReq{
							UserId:     &userinfo.UserId,
							ProductId:  productDesignInfo.ProductId,
							TemplateId: productDesignInfo.TemplateId,
							PriceId:    &productPriceInfo.Id,
							DesignId:   &productDesignInfo.Id,
							MaterialId: productDesignInfo.MaterialId,
							Status:     &cartStatus,
						}
						cartInfo, err := cartModel.FindOneCartByParams(l.ctx, cartReq)
						if err == nil && (err != nil && errors.Is(err, gorm.ErrRecordNotFound)) {
							now := time.Now().UTC().Unix()
							nowTime := time.Now()
							data := gmodel.FsCart{
								UserId:     &userinfo.UserId,
								ProductId:  productPriceInfo.ProductId,
								TemplateId: productDesignInfo.TemplateId,
								PriceId:    &productPriceInfo.Id,
								MaterialId: productDesignInfo.MaterialId,
								SizeId:     productDesignInfo.SizeId,
								BuyNum:     fsOrderDetail.BuyNum,
								Cover:      productDesignInfo.Cover,
								DesignId:   &productDesignInfo.Id,
								Ctime:      &now,
								Status:     &cartStatus,
								OptionalId: productDesignInfo.OptionalId,
								IsCheck:    &isCheck,
								TsTime:     &nowTime,
							}
							if cartInfo == nil {
								err = cartModel.Create(l.ctx, data)
							} else {
								err = cartModel.Update(l.ctx, cartInfo.Id, data)
							}
							if err != nil {
								logx.Error(err)
								return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to add to cart")
							}
						}
					}
				}
			}
		}
	}
	return resp.SetStatus(basic.CodeOK)
}