package api

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

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

// 产品管理
func Order(r *GinRouter) {
	r.GETJWT("/order/list", OrderList)
	r.POSTJWT("/order/delivery", OrderDelivery)
	r.GETJWT("/order/detail/:id", OrderDetail)

	//添加管理端接口
	CreateCRUD(r, "/admin/orders", &CRUDOption{
		Collection: repo.CollectionOrder,
		NewModel: func(c *gin.Context, apictx *ApiSession) (interface{}, error) {
			entity := &model.Order{}
			c.ShouldBindJSON(entity)
			entity.CreateTime = time.Now()
			if entity.Status == 0 {
				entity.Status = -1
			}
			return entity, nil
		},
		EmtyModel: func(c *gin.Context, apictx *ApiSession) interface{} {
			return &model.Product{}
		},
		SearchSort: bson.M{"createTime": -1},
		SearchFilter: func(c *gin.Context, apictx *ApiSession, query map[string]interface{}) map[string]interface{} {
			if query["supplyId"] != nil {
				query["supplyId"], _ = primitive.ObjectIDFromHex(query["supplyId"].(string))
			}
			if query["userId"] != nil {
				query["userId"], _ = primitive.ObjectIDFromHex(query["userId"].(string))
			}
			return query
		},
		SearchPostProcess: func(page *repo.PageResult, c *gin.Context, apictx *ApiSession, query map[string]interface{}) (interface{}, error) {
			return page, nil
		},
		JWT:           true,
		SearchProject: []string{"remark", "createTime", "status", "supplyId", "userId"},
	})
}

// 订单列表
func OrderList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	page, size, query := UtilQueryPageSize(c)
	_userId := apictx.User.ID
	userId, _ := primitive.ObjectIDFromHex(_userId)
	// 供应商的订单列表
	query["supplyId"] = 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 {
			orderCount := 0
			notShipCount := 0

			// 客户信息
			customUserId := v["userId"].(primitive.ObjectID)
			customerUser := model.UserSmaple{}
			repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
				Db:          "customer-user",
				CollectName: "users",
				Query:       repo.Map{"_id": customUserId},
			}, &customerUser)
			v["customer"] = customerUser

			// 统计下单数和未发货数
			orderCount = len(v["products"].(primitive.A))
			if orderCount > 0 {
				for _, p := range v["products"].(primitive.A) {
					if p.(map[string]interface{})["status"].(int32) == -1 {
						notShipCount++
					}
				}
			}
			v["orderCount"] = orderCount
			v["notShipCount"] = notShipCount
		}
	}

	return result, err
}

// 发货
type OrderDeliveryReq struct {
	Id        primitive.ObjectID `json:"id"`
	UniqueId  primitive.ObjectID `json:"uniqueId"`
	ExpressNo string             `json:"expressNo"`
}

func OrderDelivery(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	var form OrderDeliveryReq
	err := c.ShouldBind(&form)
	if err != nil {
		return nil, errors.New("参数错误")
	}
	// 验证订单是不是自己的
	_userId := apictx.User.ID
	fmt.Println(_userId)
	fmt.Println(form.Id.Hex())
	fmt.Println(form.UniqueId.Hex())

	userId, _ := primitive.ObjectIDFromHex(_userId)
	order := model.Order{}
	found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
		CollectName: repo.CollectionOrder,
		Query:       repo.Map{"_id": form.Id},
	}, &order)
	if !found || err != nil {
		return nil, errors.New("该订单未找到")
	}
	fmt.Println(order.SupplyId)
	if userId != order.SupplyId {
		return nil, errors.New("非法操作")
	}
	if len(order.Products) < 1 {
		return nil, errors.New("无效订单")
	}
	// 发货
	result, err := repo.RepoDocArrayOneUpdate(apictx.CreateRepoCtx(), &repo.ArrayOneUpdateOption{
		CollectName: repo.CollectionOrder,
		Id:          form.Id.Hex(),
		Query:       repo.Map{"products.id": form.UniqueId},
		Set:         repo.Map{"products.$.status": 1, "products.$.expressNo": form.ExpressNo},
	})
	if err != nil {
		fmt.Println(err)
		return nil, errors.New("发货商品异常")
	}

	if result.ModifiedCount > 0 {

		// 查询更改后的订单
		order1 := model.Order{}
		repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
			CollectName: repo.CollectionOrder,
			Query:       repo.Map{"_id": form.Id},
		}, &order1)

		// 查询其中产品 判断订单状态
		// 该订单产品有多少种状态 在此时订单只有-1，1两种状态
		statusMap := make(map[int]struct{})
		for _, v := range order1.Products {
			statusMap[v.Status] = struct{}{}
		}
		status := order.Status
		// 只有一种状态时为已发货
		if len(statusMap) == 1 {
			status = 1
		}
		// 有两种状态时为待发货
		if len(statusMap) == 2 {
			status = -1
		}
		// 发货成功该订单不可取消
		repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionOrder, form.Id.Hex(), &model.Order{Status: status, IsCancel: -1})
	}

	return result, nil
}

// 订单信息
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("数据未找到")
	}
	// 客户信息
	customer := model.UserSmaple{}
	repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
		Db:          "customer-user",
		CollectName: "users",
		Query:       repo.Map{"_id": result["userId"].(primitive.ObjectID)},
	}, &customer)
	result["customer"] = customer

	return result, nil
}
