package mall

import (
	"errors"
	"github.com/jinzhu/copier"
	"main.go/global"
	"main.go/model/common"
	"main.go/model/common/enum"
	"main.go/model/mall"
	mallRes "main.go/model/mall/response"
	"main.go/model/manage"
	manageReq "main.go/model/manage/request"
	"main.go/utils"
	"time"
)

type MallOrderService struct {
}

// SaveOrder 保存订单
func (m *MallOrderService) SaveOrder(token string, userAddress mall.MallUserAddress, myShoppingCartItems []mallRes.CartItemResponse) (err error, orderNo string) {
	var userToken mall.MallUserToken
	var userInfo mall.MallUser
	err = global.GVA_DB.Where("token =?", token).First(&userToken).Error
	if err != nil {
		return errors.New("Несуществующие пользователи"), orderNo
	}

	err = global.GVA_DB.Where("user_id =?", userToken.UserId).First(&userInfo).Error
	if userInfo != (mall.MallUser{}) {
		errors.New("Не удалось выполнить запрос пользователя заказа！")
	}

	var itemIdList []int
	var goodsIds []int
	for _, cartItem := range myShoppingCartItems {
		itemIdList = append(itemIdList, cartItem.CartItemId)
		goodsIds = append(goodsIds, cartItem.GoodsId)
	}
	var newBeeMallGoods []manage.MallGoodsInfo
	global.GVA_DB.Where("goods_id in ? ", goodsIds).Find(&newBeeMallGoods)
	//检查是否包含已下架商品
	for _, mallGoods := range newBeeMallGoods {
		if mallGoods.GoodsSellStatus != enum.GOODS_UNDER.Code() {
			return errors.New("Выставлен на продажу, не способен генерировать заказы"), orderNo
		}
	}
	newBeeMallGoodsMap := make(map[int]manage.MallGoodsInfo)
	for _, mallGoods := range newBeeMallGoods {
		newBeeMallGoodsMap[mallGoods.GoodsId] = mallGoods
	}
	//判断商品库存
	for _, shoppingCartItemVO := range myShoppingCartItems {
		//查出的商品中不存在购物车中的这条关联商品数据，直接返回错误提醒
		if _, ok := newBeeMallGoodsMap[shoppingCartItemVO.GoodsId]; !ok {
			return errors.New("Исключения данных корзины покупок！"), orderNo
		}
		if shoppingCartItemVO.GoodsCount > newBeeMallGoodsMap[shoppingCartItemVO.GoodsId].StockNum {
			return errors.New("Недостаточный запас！"), orderNo
		}
	}
	//删除购物车商品项
	if len(itemIdList) > 0 && len(goodsIds) > 0 {
		if err = global.GVA_DB.Where("cart_item_id in ?", itemIdList).Updates(mall.MallShoppingCartItem{IsDeleted: 1}).Error; err == nil {
			var stockNumDTOS []manageReq.StockNumDTO
			copier.Copy(&stockNumDTOS, &myShoppingCartItems)
			for _, stockNumDTO := range stockNumDTOS {
				var goodsInfo manage.MallGoodsInfo
				global.GVA_DB.Where("goods_id =?", stockNumDTO.GoodsId).First(&goodsInfo)
				if err = global.GVA_DB.Where("goods_id =? and stock_num>= ? and goods_sell_status = 0", stockNumDTO.GoodsId, stockNumDTO.GoodsCount).Updates(manage.MallGoodsInfo{StockNum: goodsInfo.StockNum - stockNumDTO.GoodsCount}).Error; err != nil {
					return errors.New("Недостаточный запас！" + err.Error()), orderNo
				}
			}
			//生成订单号
			orderNo = utils.GenOrderNo()
			priceTotal := 0
			//保存订单
			var newBeeMallOrder manage.MallOrder
			newBeeMallOrder.OrderNo = orderNo
			newBeeMallOrder.UserId = userToken.UserId
			newBeeMallOrder.AgentId = userToken.AgentId
			newBeeMallOrder.UserName = userInfo.LoginName
			//总价
			for _, newBeeMallShoppingCartItemVO := range myShoppingCartItems {
				priceTotal = priceTotal + newBeeMallShoppingCartItemVO.GoodsCount*newBeeMallShoppingCartItemVO.SellingPrice
			}
			if priceTotal < 1 {
				return errors.New("Аномалии цены заказа！priceTotal < 1"), orderNo
			}
			newBeeMallOrder.CreateTime = common.JSONTime{Time: time.Now()}
			newBeeMallOrder.UpdateTime = common.JSONTime{Time: time.Now()}
			newBeeMallOrder.TotalPrice = priceTotal
			newBeeMallOrder.ExtraInfo = ""
			//生成订单项并保存订单项纪录
			if err = global.GVA_DB.Save(&newBeeMallOrder).Error; err != nil {
				return errors.New("Сбой ввода заказа！" + err.Error()), orderNo
			}
			//生成订单收货地址快照，并保存至数据库
			var newBeeMallOrderAddress mall.MallOrderAddress
			copier.Copy(&newBeeMallOrderAddress, &userAddress)
			newBeeMallOrderAddress.OrderId = newBeeMallOrder.OrderId
			//生成所有的订单项快照，并保存至数据库
			var newBeeMallOrderItems []manage.MallOrderItem
			for _, newBeeMallShoppingCartItemVO := range myShoppingCartItems {
				var newBeeMallOrderItem manage.MallOrderItem
				copier.Copy(&newBeeMallOrderItem, &newBeeMallShoppingCartItemVO)
				newBeeMallOrderItem.OrderId = newBeeMallOrder.OrderId
				newBeeMallOrderItem.CreateTime = common.JSONTime{Time: time.Now()}
				newBeeMallOrderItems = append(newBeeMallOrderItems, newBeeMallOrderItem)
			}
			if err = global.GVA_DB.Save(&newBeeMallOrderItems).Error; err != nil {
				return err, orderNo
			}
		}
	}
	return
}

// PaySuccess 支付订单
func (m *MallOrderService) PaySuccess(orderNo string, payType int) (err error) {
	var mallOrder manage.MallOrder
	var userInfo mall.MallUser
	//余额 >商品总价  支付成功，否则失败
	err = global.GVA_DB.Where("order_no = ? and is_deleted=0 ", orderNo).First(&mallOrder).Error

	if mallOrder != (manage.MallOrder{}) {
		errors.New("Заказ не существует, пожалуйста, сделайте повторный заказ！")
	}

	//查出用户的钱
	//判断 余额 是否 大于商品H
	//扣款

	err = global.GVA_DB.Where("user_id =?", mallOrder.UserId).First(&userInfo).Error
	if userInfo != (mall.MallUser{}) {
		errors.New("Ошибка входа в систему, войдите снова！1233")
	}
	userBalance := userInfo.UserMoney - mallOrder.TotalPrice
	if userBalance >= 0 {
		global.GVA_DB.Model(&userInfo).Update("user_money", userBalance)
	} else {
		return errors.New("Недостаточный баланс, пожалуйста, пополните！1244")
	}

	mallOrder.OrderStatus = enum.ORDER_PAID.Code()
	mallOrder.PayType = payType
	mallOrder.PayStatus = 1
	mallOrder.AgentId = userInfo.AgentId
	mallOrder.UserName = userInfo.LoginName
	mallOrder.PayTime = common.JSONTime{time.Now()}
	mallOrder.UpdateTime = common.JSONTime{time.Now()}
	err = global.GVA_DB.Save(&mallOrder).Error

	return
}

// FinishOrder 完结订单
func (m *MallOrderService) FinishOrder(token string, orderNo string) (err error) {
	var userToken mall.MallUserToken
	err = global.GVA_DB.Where("token =?", token).First(&userToken).Error
	if err != nil {
		return errors.New("Несуществующие пользователи")
	}
	var mallOrder manage.MallOrder
	if err = global.GVA_DB.Where("order_no=? and is_deleted = 0", orderNo).First(&mallOrder).Error; err != nil {
		return errors.New("Записи не изучались！")
	}
	if mallOrder.UserId != userToken.UserId {
		return errors.New("Отключить эту операцию！")
	}
	mallOrder.OrderStatus = enum.ORDER_SUCCESS.Code()
	mallOrder.UpdateTime = common.JSONTime{time.Now()}
	err = global.GVA_DB.Save(&mallOrder).Error
	return
}

// CancelOrder 关闭订单
func (m *MallOrderService) CancelOrder(token string, orderNo string) (err error) {
	var userToken mall.MallUserToken
	err = global.GVA_DB.Where("token =?", token).First(&userToken).Error
	if err != nil {
		return errors.New("Несуществующие пользователи")
	}
	var mallOrder manage.MallOrder
	if err = global.GVA_DB.Where("order_no=? and is_deleted = 0", orderNo).First(&mallOrder).Error; err != nil {
		return errors.New("Записи не изучались！")
	}
	if mallOrder.UserId != userToken.UserId {
		return errors.New("Отключить эту операцию！")
	}
	if utils.NumsInList(mallOrder.OrderStatus, []int{enum.ORDER_SUCCESS.Code(),
		enum.ORDER_CLOSED_BY_MALLUSER.Code(), enum.ORDER_CLOSED_BY_EXPIRED.Code(), enum.ORDER_CLOSED_BY_JUDGE.Code()}) {
		return errors.New("Исключения из статуса заказа！")
	}
	mallOrder.OrderStatus = enum.ORDER_CLOSED_BY_MALLUSER.Code()
	mallOrder.UpdateTime = common.JSONTime{time.Now()}
	err = global.GVA_DB.Save(&mallOrder).Error
	return
}

// GetOrderDetailByOrderNo 获取订单详情

func (m *MallOrderService) GetOrderDetailByOrderNo(token string, orderNo string) (err error, orderDetail mallRes.MallOrderDetailVO) {
	var userToken mall.MallUserToken
	err = global.GVA_DB.Where("token =?", token).First(&userToken).Error
	if err != nil {
		return errors.New("Несуществующие пользователи"), orderDetail
	}
	var mallOrder manage.MallOrder
	if err = global.GVA_DB.Where("order_no=? and is_deleted = 0", orderNo).First(&mallOrder).Error; err != nil {
		return errors.New("Записи не изучались！"), orderDetail
	}
	if mallOrder.UserId != userToken.UserId {
		return errors.New("Отключите эту операцию! Несоответствующий идентификатор входа пользователя"), orderDetail
	}
	var orderItems []manage.MallOrderItem
	err = global.GVA_DB.Where("order_id = ?", mallOrder.OrderId).Find(&orderItems).Error
	if len(orderItems) <= 0 {
		return errors.New("Пункт заказа не существует！"), orderDetail
	}

	var newBeeMallOrderItemVOS []mallRes.NewBeeMallOrderItemVO
	copier.Copy(&newBeeMallOrderItemVOS, &orderItems) // &orderItems 的值 复制 到 &newBeeMallOrderItemVOS
	copier.Copy(&orderDetail, &mallOrder)
	// 订单状态前端显示为中文
	_, OrderStatusStr := enum.GetNewBeeMallOrderStatusEnumByStatus(orderDetail.OrderStatus)
	_, payTapStr := enum.GetNewBeeMallOrderStatusEnumByStatus(orderDetail.PayType)
	orderDetail.OrderStatusString = OrderStatusStr
	orderDetail.PayTypeString = payTapStr
	orderDetail.NewBeeMallOrderItemVOS = newBeeMallOrderItemVOS

	return
}

// MallOrderListBySearch 搜索订单
func (m *MallOrderService) MallOrderListBySearch(token string, pageNumber int, status string) (err error, list []mallRes.MallOrderResponse, total int64) {
	var userToken mall.MallUserToken
	err = global.GVA_DB.Where("token =?", token).First(&userToken).Error
	if err != nil {
		return errors.New("Несуществующие пользователи"), list, total
	}
	// 根据搜索条件查询
	var newBeeMallOrders []manage.MallOrder
	db := global.GVA_DB.Model(&newBeeMallOrders)

	if status != "" {
		db.Where("order_status = ?", status)
	}
	err = db.Where("user_id =? and is_deleted=0 ", userToken.UserId).Count(&total).Error
	limit := 80
	offset := 80 * (pageNumber - 1)
	err = db.Limit(limit).Offset(offset).Find(&newBeeMallOrders).Error

	var orderListVOS []mallRes.MallOrderResponse
	if total > 0 {
		//数据转换 将实体类转成vo
		copier.Copy(&orderListVOS, &newBeeMallOrders)
		//设置订单状态中文显示值
		for _, newBeeMallOrderListVO := range orderListVOS {
			_, statusStr := enum.GetNewBeeMallOrderStatusEnumByStatus(newBeeMallOrderListVO.OrderStatus)
			newBeeMallOrderListVO.OrderStatusString = statusStr
		}
		// 返回订单id
		var orderIds []int
		for _, order := range newBeeMallOrders {
			orderIds = append(orderIds, order.OrderId)
		}
		//获取OrderItem
		var orderItems []manage.MallOrderItem
		if len(orderIds) > 0 {
			global.GVA_DB.Where("order_id in ?", orderIds).Find(&orderItems)
			itemByOrderIdMap := make(map[int][]manage.MallOrderItem)
			for _, orderItem := range orderItems {
				itemByOrderIdMap[orderItem.OrderId] = []manage.MallOrderItem{}
			}
			for k, v := range itemByOrderIdMap {
				for _, orderItem := range orderItems {
					if k == orderItem.OrderId {
						v = append(v, orderItem)
					}
					itemByOrderIdMap[k] = v
				}
			}
			//封装每个订单列表对象的订单项数据
			for _, newBeeMallOrderListVO := range orderListVOS {
				if _, ok := itemByOrderIdMap[newBeeMallOrderListVO.OrderId]; ok {
					orderItemListTemp := itemByOrderIdMap[newBeeMallOrderListVO.OrderId]
					var newBeeMallOrderItemVOS []mallRes.NewBeeMallOrderItemVO
					copier.Copy(&newBeeMallOrderItemVOS, &orderItemListTemp)
					newBeeMallOrderListVO.NewBeeMallOrderItemVOS = newBeeMallOrderItemVOS
					_, OrderStatusStr := enum.GetNewBeeMallOrderStatusEnumByStatus(newBeeMallOrderListVO.OrderStatus)
					newBeeMallOrderListVO.OrderStatusString = OrderStatusStr
					list = append(list, newBeeMallOrderListVO)
				}
			}
		}
	}
	return err, list, total
}
