package api

import (
	"box-cost/db/model"
	"box-cost/db/repo"
	"box-cost/log"
	"errors"
	"fmt"
	"time"

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

// 供应商价格管理
func SupplierPrice(r *GinRouter) {

	// // 创建供应商价格
	// r.POST("/supplier/mat/create", CreateSupplierPrice)

	// // 获取供应商价格列表
	// r.GET("/supplier/mat/list", GetSupplierPrices)

	// // 更新供应商价格
	// r.POST("/supplier/mat/update", UpdateSupplierPrice)

	// // 删除供应商价格
	// r.POST("/supplier/mat/delete/:id", DelSupplierPrice)

	//材料供应

	CreateCRUD(r, "/supplier/mat", &CRUDOption{
		Collection: repo.CollectionSupplierMatprice,
		NewModel: func(c *gin.Context, apictx *ApiSession) (interface{}, error) {
			entity := &model.SupplierPrice{}
			c.ShouldBindJSON(entity)
			if entity.ProductId == primitive.NilObjectID || entity.SupplierId == primitive.NilObjectID {
				return nil, fmt.Errorf("产品ID或供应商Id不能为空")
			}

			curr := &model.SupplierPrice{}
			ok, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
				CollectName: repo.CollectionSupplierMatprice,
				Query:       repo.Map{"productId": entity.ProductId, "supplierId": entity.SupplierId},
				Project:     []string{"_id"},
			}, curr)
			if err != nil {
				return nil, err
			}
			if ok {
				return nil, fmt.Errorf("该材料已经在供应列表里面了")
			}

			entity.CreateTime = time.Now()
			entity.UpdateTime = time.Now()

			return entity, nil
		},
		EmtyModel: func(c *gin.Context, apictx *ApiSession) interface{} {
			return &model.SupplierPrice{}
		},
		JWT: true,
		OnUpdate: func(c *gin.Context, apictx *ApiSession, entity interface{}) {
			calc := entity.(*model.SupplierPrice)
			calc.UpdateTime = time.Now()
		},
		SearchFilter: func(c *gin.Context, apictx *ApiSession, query map[string]interface{}) map[string]interface{} {
			if query["supplierId"] != nil {
				query["supplierId"], _ = primitive.ObjectIDFromHex(query["supplierId"].(string))
			}
			if query["productId"] != nil {
				query["productId"], _ = primitive.ObjectIDFromHex(query["productId"].(string))
			}
			return query
		},

		SearchPostProcess: func(page *repo.PageResult, c *gin.Context, apictx *ApiSession, query map[string]interface{}) (interface{}, error) {
			//查询材料对应的材料信息
			for _, mat := range page.List {
				_id, _ := mat["productId"].(primitive.ObjectID)

				matInfo := &model.Material{}
				repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
					CollectName: repo.CollectionMaterial,
					Query:       repo.Map{"_id": _id},
				}, matInfo)
				mat["matInfo"] = matInfo
			}
			return page, nil
		},

		SearchProject: []string{"price", "supplierId", "productId", "updateTime", "_id"},
	})

	CreateCRUD(r, "/supplier/craft", &CRUDOption{
		Collection: repo.CollectionSupplierCraftprice,
		NewModel: func(c *gin.Context, apictx *ApiSession) (interface{}, error) {
			entity := &model.SupplierPrice{}
			c.ShouldBindJSON(entity)

			if entity.ProductId == primitive.NilObjectID || entity.SupplierId == primitive.NilObjectID {
				return nil, fmt.Errorf("产品ID或供应商Id不能为空")
			}

			curr := &model.SupplierPrice{}
			ok, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
				CollectName: repo.CollectionSupplierCraftprice,
				Query:       repo.Map{"productId": entity.ProductId, "supplierId": entity.SupplierId},
				Project:     []string{"_id"},
			}, curr)
			if err != nil {
				return nil, err
			}
			if ok {
				return nil, fmt.Errorf("该工艺已经在供应列表里面了")
			}

			entity.CreateTime = time.Now()
			entity.UpdateTime = time.Now()
			return entity, nil
		},
		EmtyModel: func(c *gin.Context, apictx *ApiSession) interface{} {
			return &model.SupplierPrice{}
		},
		JWT: true,
		OnUpdate: func(c *gin.Context, apictx *ApiSession, entity interface{}) {
			calc := entity.(*model.SupplierPrice)
			calc.UpdateTime = time.Now()
		},
		SearchFilter: func(c *gin.Context, apictx *ApiSession, query map[string]interface{}) map[string]interface{} {
			if query["supplierId"] != nil {
				query["supplierId"], _ = primitive.ObjectIDFromHex(query["supplierId"].(string))
			}
			if query["productId"] != nil {
				query["productId"], _ = primitive.ObjectIDFromHex(query["productId"].(string))
			}
			return query
		},
		SearchPostProcess: func(page *repo.PageResult, c *gin.Context, apictx *ApiSession, query map[string]interface{}) (interface{}, error) {
			//查询材料对应的材料信息
			for _, mat := range page.List {
				_id, _ := mat["productId"].(primitive.ObjectID)

				craft := &model.Craft{}
				repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
					CollectName: repo.CollectionCraft,
					Query:       repo.Map{"_id": _id},
				}, craft)
				mat["craftInfo"] = craft
			}
			return page, nil
		},
		SearchProject: []string{"price", "supplierId", "productId", "updateTime", "_id"},
	})

	CreateCRUD(r, "/supplier/product", &CRUDOption{
		Collection: repo.CollectionSupplierProductprice,
		NewModel: func(c *gin.Context, apictx *ApiSession) (interface{}, error) {
			entity := &model.SupplierPrice{}
			c.ShouldBindJSON(entity)

			if entity.ProductId == primitive.NilObjectID || entity.SupplierId == primitive.NilObjectID {
				return nil, fmt.Errorf("产品ID或供应商Id不能为空")
			}

			curr := &model.SupplierPrice{}
			ok, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
				CollectName: repo.CollectionSupplierProductprice,
				Query:       repo.Map{"productId": entity.ProductId, "supplierId": entity.SupplierId},
				Project:     []string{"_id"},
			}, curr)
			if err != nil {
				return nil, err
			}
			if ok {
				return nil, fmt.Errorf("该工序已经在供应列表里面了")
			}

			entity.CreateTime = time.Now()
			entity.UpdateTime = time.Now()
			return entity, nil
		},
		EmtyModel: func(c *gin.Context, apictx *ApiSession) interface{} {
			return &model.SupplierPrice{}
		},
		JWT: true,
		OnUpdate: func(c *gin.Context, apictx *ApiSession, entity interface{}) {
			calc := entity.(*model.SupplierPrice)
			calc.UpdateTime = time.Now()
		},
		SearchFilter: func(c *gin.Context, apictx *ApiSession, query map[string]interface{}) map[string]interface{} {
			if query["supplierId"] != nil {
				query["supplierId"], _ = primitive.ObjectIDFromHex(query["supplierId"].(string))
			}
			if query["productId"] != nil {
				query["productId"], _ = primitive.ObjectIDFromHex(query["productId"].(string))
			}
			return query
		},
		SearchPostProcess: func(page *repo.PageResult, c *gin.Context, apictx *ApiSession, query map[string]interface{}) (interface{}, error) {
			//查询材料对应的材料信息
			for _, ps := range page.List {
				_id, _ := ps["productId"].(primitive.ObjectID)

				process := &model.Product{}
				repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
					CollectName: repo.CollectionProduct,
					Query:       repo.Map{"_id": _id},
				}, process)
				ps["processInfo"] = process
			}
			return page, nil
		},
		SearchProject: []string{"price", "supplierId", "productId", "updateTime", "_id"},
	})

	//添加计价方案
	SupplierCalcPriceColl := "supplier-calcprice"
	CreateCRUD(r, "/supplier/calc", &CRUDOption{
		Collection: SupplierCalcPriceColl,
		NewModel: func(c *gin.Context, apictx *ApiSession) (interface{}, error) {
			entity := &model.SupplierCalcPrice{}
			c.ShouldBindJSON(entity)
			if entity.SupplierId == primitive.NilObjectID {
				return nil, fmt.Errorf("供应商Id不能为空")
			}
			if entity.Calc == nil || len(entity.Calc.Category) < 1 {
				return nil, fmt.Errorf("计价方案参数错误")
			}
			calc := &model.SupplierCalcPrice{}
			ok, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(),
				&repo.DocSearchOptions{CollectName: SupplierCalcPriceColl,
					Query: repo.Map{"calc.category": entity.Calc.Category, "supplierId": entity.SupplierId}}, calc)
			if err != nil {
				return nil, err
			}
			if ok {
				return nil, fmt.Errorf("相同的分类计价方案只能有一个")
			}
			entity.CreateTime = time.Now()
			entity.UpdateTime = time.Now()
			return entity, nil
		},
		EmtyModel: func(c *gin.Context, apictx *ApiSession) interface{} {
			return &model.SupplierCalcPrice{}
		},
		JWT: true,
		OnUpdate: func(c *gin.Context, apictx *ApiSession, entity interface{}) {
			calc := entity.(*model.SupplierCalcPrice)
			calc.UpdateTime = time.Now()
		},
		SearchFilter: func(c *gin.Context, apictx *ApiSession, query map[string]interface{}) map[string]interface{} {
			if query["supplierId"] != nil {
				query["supplierId"], _ = primitive.ObjectIDFromHex(query["supplierId"].(string))
			}
			return query
		},
		SearchProject: []string{"calc", "supplierId", "updateTime", "_id"},
	})
}

// 创建供应商价格
func CreateSupplierPrice(c *gin.Context, apictx *ApiSession) (interface{}, error) {

	var supplierprice model.SupplierPrice

	err := c.ShouldBindJSON(&supplierprice)
	if err != nil {
		fmt.Println(err)
		return nil, errors.New("参数错误！")
	}
	ctx := apictx.CreateRepoCtx()

	if supplierprice.SupplierId.Hex() == "" {
		return nil, errors.New("供应商id为空")
	}
	// if supplierprice.ProductId.Hex() == "" {
	// 	return nil, errors.New("供应产品id为空")
	// }
	// if supplierprice.PriceStrategy == nil {
	// 	return nil, errors.New("供应商价格策略为空")
	// }

	supplierprice.CreateTime = time.Now()
	supplierprice.UpdateTime = time.Now()

	result, err := repo.RepoAddDoc(ctx, repo.CollectionSupplierPrice, &supplierprice)
	return result, err
}

// 获取供应商价格信息
func GetSupplierPrice(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	supplierpriceId := c.Param("id")
	id, err := primitive.ObjectIDFromHex(supplierpriceId)
	if err != nil {
		return nil, errors.New("非法id")
	}
	var supplierprice model.SupplierPrice
	option := &repo.DocSearchOptions{
		CollectName: repo.CollectionSupplierPrice,
		Query:       repo.Map{"_id": id},
	}

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

	return supplierprice, nil
}

// 获取供应商价格列表
func GetSupplierPrices(c *gin.Context, apictx *ApiSession) (interface{}, error) {

	page, size, query := UtilQueryPageSize(c)

	option := &repo.PageSearchOptions{
		CollectName: repo.CollectionSupplierPrice,
		Query:       query,
		Page:        page,
		Size:        size,
		Sort:        bson.M{"createTime": -1},
	}
	return repo.RepoPageSearch(apictx.CreateRepoCtx(), option)
}

// 更新供应商价格
func UpdateSupplierPrice(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	var supplierprice model.SupplierPrice
	err := c.ShouldBindJSON(&supplierprice)
	if err != nil {
		return nil, errors.New("参数错误")
	}
	if supplierprice.Id.Hex() == "" {
		return nil, errors.New("id的为空")
	}
	supplierprice.UpdateTime = time.Now()
	return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionSupplierPrice, supplierprice.Id.Hex(), &supplierprice)
}

// 删除供应商价格
func DelSupplierPrice(c *gin.Context, apictx *ApiSession) (interface{}, error) {
	supplierpriceId := c.Param("id")
	if supplierpriceId == "" {
		return nil, errors.New("id为空")
	}

	return repo.RepoDeleteDoc(apictx.CreateRepoCtx(), repo.CollectionSupplierPrice, supplierpriceId)
}
