package api

import (
	"3dshow-customer/db/model"
	"3dshow-customer/db/repo"
	"errors"
	"fmt"
	"time"

	"github.com/gin-gonic/gin"
	"go.mongodb.org/mongo-driver/bson/primitive"
)

// 产品管理
func Order(r *GinRouter) {
	r.POSTJWT("/order/createBatch", OrderAddBatch)
	r.GETJWT("/order/list", OrderList)
	r.POSTJWT("/order/cancelOrComplete/:id", OrderCancelOrComplete)
	r.GETJWT("/order/detail/:id", OrderDetail)
	r.GETJWT("/order/count", OrderCount)
}

// 批量新增订单
func OrderAddBatch(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	var orders []*model.OrderAddReq
	err := c.ShouldBindJSON(&orders)
	if err != nil {
		fmt.Println(err)
		return nil, errors.New("参数错误！")
	}
	ctx := apictx.CreateRepoCtx()
	_userId := apictx.User.ID
	userId, _ := primitive.ObjectIDFromHex(_userId)

	if len(orders) < 1 {
		return nil, errors.New("购物车为空")
	}

	for _, v := range orders {
		order := &model.Order{}
		order.UserId = userId
		order.SupplyId = v.Supply.Id
		order.Address = v.Address
		// order.Products
		// 组装商品和设置默认状态
		if len(v.Products) > 0 {
			for _, p := range v.Products {
				order.Products = append(order.Products, &model.OrderProduct{
					Id:        primitive.NewObjectID(),
					ProductId: p.ProductId,
					SupplyId:  p.SupplyId,
					Name:      p.Name,
					Size:      p.Size,
					Color:     p.Color,
					Unit:      p.Unit,
					Cover:     p.Cover,
					ExpressNo: "",
					Status:    -1,
				})
				// 加入购物车后 删除购物车对应商品
				repo.RepoDeleteDoc(ctx, repo.CollectionShopCart, p.Id.Hex())

			}
		}
		order.DeliveryMethod = v.DeliveryMethod
		order.Remark = v.Remark
		order.Status = -1
		order.IsCancel = 1
		order.CreateTime = time.Now()
		repo.RepoAddDoc(ctx, repo.CollectionOrder, order)

	}

	return true, nil

}

// 订单列表
func OrderList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	page, size, query := UtilQueryPageSize(c)
	_userId := apictx.User.ID
	userId, _ := primitive.ObjectIDFromHex(_userId)
	query["userId"] = userId

	result, err := repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
		CollectName: repo.CollectionOrder,
		Page:        page,
		Size:        size,
		Query:       query,
		Project:     []string{"createTime", "userId", "supplyId", "products", "status"},
		Sort:        repo.Map{"createTime": -1},
	})

	if len(result.List) > 0 {
		for _, v := range result.List {
			supplyId := v["supplyId"].(primitive.ObjectID)
			supply := model.UserSmaple{}
			repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
				Db:          "supply-user",
				CollectName: "users",
				Query:       repo.Map{"_id": supplyId},
			}, &supply)
			v["supplyName"] = supply.Name
		}
	}

	return result, err
}

// 个人页面数量展示
func OrderCount(_ *gin.Context, apictx *ApiSession) (interface{}, error) {
	_userId := apictx.User.ID
	userId, _ := primitive.ObjectIDFromHex(_userId)

	statusArray := []int{-1, 1, 2, 3}
	resMap := make(map[int]int64)
	// var ret []int64
	ctx := apictx.CreateRepoCtx()
	for _, v := range statusArray {
		query := repo.Map{"userId": userId, "status": v}
		res, _ := repo.RepoCountDoc(ctx, repo.CollectionOrder, query)
		// ret = append(ret, res)
		resMap[v] = res
	}
	return resMap, nil
}

// 订单取消和完成操作
func OrderCancelOrComplete(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	// 订单中每个商品都处于未发货状态
	_id := c.Param("id")
	if len(_id) < 1 {
		return nil, errors.New("id不能为空")
	}
	orderId, err := primitive.ObjectIDFromHex(_id)
	if err != nil {
		return nil, errors.New("id非法")
	}
	order := model.Order{}
	found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
		CollectName: repo.CollectionOrder,
		Query:       repo.Map{"_id": orderId},
	}, &order)
	if !found || err != nil {
		return nil, errors.New("未找到该订单数据")
	}
	if len(order.Products) < 1 {
		return nil, errors.New("该订单为空")
	}
	// 操作人非订单所属人
	if order.UserId.Hex() != apictx.User.ID {
		return nil, errors.New("非法操作")
	}

	statusMap := map[int]struct{}{}
	for _, v := range order.Products {
		statusMap[v.Status] = struct{}{}
	}

	// 状态为一种
	if len(statusMap) == 1 {
		// 且都为未发货状态时 可以取消订单
		// 取消流程
		if _, ok := statusMap[-1]; ok && order.Status == -1 {
			// 更新产品状态
			for _, p := range order.Products {
				repo.RepoDocArrayOneUpdate(apictx.CreateRepoCtx(), &repo.ArrayOneUpdateOption{
					CollectName: repo.CollectionOrder,
					Id:          order.Id.Hex(),
					Query:       repo.Map{"products.id": p.Id},
					Set:         repo.Map{"products.$.status": 3},
				})

			}

			return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionOrder, _id, &model.Order{Status: 3, IsCancel: -1})
		}

		// 且都为已发货状态时 可以取消订单
		// 完成流程
		if _, ok := statusMap[1]; ok && order.Status == 1 {
			// 更新产品状态
			for _, p := range order.Products {
				repo.RepoDocArrayOneUpdate(apictx.CreateRepoCtx(), &repo.ArrayOneUpdateOption{
					CollectName: repo.CollectionOrder,
					Id:          order.Id.Hex(),
					Query:       repo.Map{"products.id": p.Id},
					Set:         repo.Map{"products.$.status": 2},
				})

			}
			return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionOrder, _id, &model.Order{Status: 2, IsCancel: -1})
		}
	}

	return nil, errors.New("该订单不满足取消或完成操作")
}

// 订单信息
func OrderDetail(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	_id := c.Param("id")
	if len(_id) < 1 {
		return nil, errors.New("id不能为空")
	}
	orderId, err := primitive.ObjectIDFromHex(_id)
	if err != nil {
		return nil, errors.New("非法id")
	}
	ok, result := repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
		CollectName: repo.CollectionOrder,
		Query:       repo.Map{"_id": orderId},
	})
	if !ok {
		return nil, errors.New("数据未找到")
	}
	// 供应链信息
	supply := model.UserSmaple{}
	repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
		Db:          "supply-user",
		CollectName: "users",
		Query:       repo.Map{"_id": result["supplyId"].(primitive.ObjectID)},
	}, &supply)
	result["supply"] = supply

	return result, nil
}
