package api

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

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

// 产品管理
func Product(r *GinRouter) {
	r.POSTJWT("/product/create", ProductAdd)
	r.POSTJWT("/product/update", ProductUpdate)
	r.GETJWT("/product/list", ProductList)
	r.POSTJWT("/product/onOrOffShelves/:id", OnOrOffShelves)
	r.GETJWT("/product/detail/:id", ProductDetail)
	r.GET("/product/share/detail/:id", ProductDetail)
	r.POSTJWT("/product/delete/:id", ProductDelete)

	//添加管理端接口
	CreateCRUD(r, "/admin/products", &CRUDOption{
		Collection: repo.CollectionProduct,
		NewModel: func(c *gin.Context, apictx *ApiSession) (interface{}, error) {
			entity := &model.Product{}
			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))
			}
			return query
		},
		JWT:           true,
		SearchProject: []string{"name", "createTime", "type", "unit", "price", "cover", "status"},
	})
}

// 新增产品
func ProductAdd(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	var form model.Product
	err := c.ShouldBindJSON(&form)
	if err != nil {
		return nil, errors.New("参数错误！")
	}
	_userId := apictx.User.ID
	userId, _ := primitive.ObjectIDFromHex(_userId)
	// 供应链端 供应id就算当前用户id
	form.SupplyId = userId
	if form.Name == "" {
		return nil, errors.New("产品名不能为空")
	}
	form.CreateTime = time.Now()
	// 状态默认为下架
	if form.Status == 0 {
		form.Status = -1
	}
	if form.Status == 1 {
		form.OnsaleTime = time.Now()
	}

	result, err := repo.RepoAddDoc(apictx.CreateRepoCtx(), repo.CollectionProduct, &form)
	return result, err

}

// 更新产品/编辑、下架
func ProductUpdate(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	var form model.Product
	err := c.ShouldBindJSON(&form)
	if err != nil {
		return nil, errors.New("参数错误")
	}
	if form.Id.Hex() == "" {
		return nil, errors.New("产品id不能为空")
	}
	product := model.Product{}
	found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
		CollectName: repo.CollectionProduct,
		Query:       repo.Map{"_id": form.Id},
	}, &product)
	if !found || err != nil {
		return nil, errors.New("该商品不存在")
	}

	// 不是自己的商品
	if product.SupplyId.Hex() != apictx.User.ID {
		return nil, errors.New("非法操作")
	}
	form.UpdateTime = time.Now()
	return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionProduct, form.Id.Hex(), &form)
}

// 上下架商品
func OnOrOffShelves(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	// 根据id查询商品
	_id := c.Param("id")
	if len(_id) < 1 {
		return nil, errors.New("商品id不能为空")
	}

	productId, err := primitive.ObjectIDFromHex(_id)
	if err != nil {
		return nil, errors.New("非法id")
	}
	product := model.Product{}
	found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
		CollectName: repo.CollectionProduct,
		Query:       repo.Map{"_id": productId},
	}, &product)
	if !found || err != nil {
		return nil, errors.New("该商品不存在")
	}

	// 不是自己的商品
	if product.SupplyId.Hex() != apictx.User.ID {
		return nil, errors.New("非法操作")
	}
	// 更新状态
	if product.Status == -1 {
		product.Status = 1
		product.OnsaleTime = time.Now()
		product.UpdateTime = time.Now()
	} else if product.Status == 1 {
		product.Status = -1
		product.UpdateTime = time.Now()
	}
	return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionProduct, _id, &product)
}

// 产品列表
func ProductList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	page, size, query := UtilQueryPageSize(c)
	// asc:升序1  desc:降序-1
	// 默认排序
	onsaleTimeSort := repo.Map{"onsaleTime": -1}
	if _, ok := query["sort"]; ok {
		if query["sort"].(string) == "asc" {
			onsaleTimeSort = repo.Map{"onsaleTime": 1}
		}
		delete(query, "sort")
	}
	// selectTime
	selectTime := time.Now()
	if _, ok := query["selectTime"]; ok {
		timeSlice := strings.Split(query["selectTime"].(string), ".")
		// timeStr := "2019-04-07 15:15:05"
		//     fmt.Println("初始：", timeStr)
		//     t, _ := time.ParseInLocation("2006-01-02 15:04:05", timeStr, time.Local)
		timeStr := fmt.Sprintf("%s%s", strings.Join(timeSlice, "-"), "-01 00:00:00")
		selectTime, _ = time.Parse("2006-01-02 15:04:05", timeStr)
	}
	query["onsaleTime"] = bson.M{"$lte": selectTime}

	// 供应商 查询自己的商品
	_userId := apictx.User.ID
	userId, _ := primitive.ObjectIDFromHex(_userId)
	query["supplyId"] = userId
	option := &repo.PageSearchOptions{
		CollectName: repo.CollectionProduct,
		Page:        page,
		Size:        size,
		Query:       query,
		// Project:     []string{},
		Sort: onsaleTimeSort,
	}
	return repo.RepoPageSearch(apictx.CreateRepoCtx(), option)
}

// 删除产品
func ProductDelete(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	_id := c.Param("id")
	if len(_id) < 1 {
		return nil, errors.New("id不能为空")
	}
	productId, err := primitive.ObjectIDFromHex(_id)
	if err != nil {
		return nil, errors.New("非法id")
	}
	product := model.Product{}
	found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
		CollectName: repo.CollectionProduct,
		Query:       repo.Map{"_id": productId},
	}, &product)
	if !found || err != nil {
		return nil, errors.New("该商品不存在")
	}
	// 不是自己的商品
	if product.SupplyId.Hex() != apictx.User.ID {
		return nil, errors.New("非法操作")
	}

	return repo.RepoDeleteDoc(apictx.CreateRepoCtx(), repo.CollectionProduct, _id)
}

// 产品信息
func ProductDetail(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	_id := c.Param("id")
	if len(_id) < 1 {
		return nil, errors.New("id不能为空")
	}
	productId, err := primitive.ObjectIDFromHex(_id)
	if err != nil {
		return nil, errors.New("非法id")
	}
	var product model.Product
	option := &repo.DocSearchOptions{
		CollectName: repo.CollectionProduct,
		Query:       repo.Map{"_id": productId},
	}

	found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), option, &product)
	if !found || err != nil {
		log.Info(err)
		return nil, errors.New("数据未找到")
	}

	return product, nil
}
