package inventorymanage

import (
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"go-admin/app/admin/models"
	"go-admin/logger"
	"go-admin/tools"
	"go-admin/tools/app"
	"io"
	"net/http"
)

type DeliveryCargoReq struct {
	Id uint32 `json:"id" binding:"required"` // 商品库存列表id
}

type AddRemarkReq struct {
	Id     int    `json:"id" binding:"required"` // 商品库存列表id
	Remark string `json:"remark"`                // 备注
}

// GetInventoryListOld 该函数只遍历了库存列表，和产品需求不符合
// 产品需要库存列表接口返回所有商品资料数据，以及每个商品的库存情况
func GetInventoryListOld(c *gin.Context) {
	req := &models.ErpStockListReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		//logger.Error(err)
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}

	resp, err := req.List()
	if err != nil {
		//logger.Error("erp commodity list err:", err)
		app.Error(c, http.StatusInternalServerError, err, "获取失败")
		return
	}

	app.OK(c, resp, "OK")
	return
}

// GetInventoryList 查询库存列表
// @Summary 查询库存列表
// @Tags 库存管理
// @Produce json
// @Accept json
// @Param request body models.ErpStockListReq true "查询库存列表模型"
// @Success 200 {object} models.ErpStockListResp
// @Router /api/v1/inventory/list [post]
func GetInventoryList(c *gin.Context) {
	req := &models.ErpStockListReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		//logger.Error(err)
		app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
		return
	}
	// 如果筛选条件有：库存情况筛选；则以库存表为准，查库存表即可
	// （1）没门店，则查所有库存情况并排序
	// （2）有门店，则查门店对应的库存情况并排序

	// 如果筛选条件没有库存情况，则先查询商品资料，并排序；支持筛选条件：商品编号、商品分类、商品名称
	// 然后查询每个商品资料的库存情况，没传门店id，则查所有库存；否则查当前门店的库存情况

	resp, err := req.StockList(c)
	if err != nil {
		//logger.Error("erp commodity list err:", err)
		app.Error(c, http.StatusInternalServerError, err, "查询失败："+err.Error())
		return
	}

	app.OK(c, resp, "OK")
	return
}

// GetInventoryDetail 查询库存详情
// @Summary 查询库存详情
// @Tags 库存管理
// @Produce json
// @Accept json
// @Param request body models.ErpStockCommodityListReq true "查询库存详情模型"
// @Success 200 {object} models.ErpStockCommodityListResp
// @Router /api/v1/inventory/detail [post]
func GetInventoryDetail(c *gin.Context) {
	req := &models.ErpStockCommodityListReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		//logger.Error(err)
		app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误")
		return
	}

	list, err := req.GetDetailList(c, 1)
	if err != nil {
		//logger.Error("erp stock err:", err)
		if err.Error() == "该商品在调拨中" {
			app.Error(c, http.StatusInternalServerError, err, err.Error())
		} else {
			app.Error(c, http.StatusInternalServerError, err, "查询失败："+err.Error())
		}
		return
	}

	if req.ScanCode != "" { // 当扫码时需要对返回的数据做校验
		err = models.CheckScanCodeResp(req.ScanCode, req.StoreId, list)
		if err != nil {
			//logger.Error("erp stock err:", err)
			app.Error(c, http.StatusInternalServerError, err, err.Error())
			return
		}
	}

	app.OK(c, list, "OK")
	return
}

// GetInventoryDetailNew 查询库存详情（详情页专用，门店复选）
// @Summary 查询库存详情（详情页专用，门店复选）
// @Tags 库存管理
// @Produce json
// @Accept json
// @Param request body models.NewErpStockCommodityListReq true "查询库存详情模型"
// @Success 200 {object} models.ErpStockCommodityListResp
// @Router /api/v1/inventory/detail_new [post]
func GetInventoryDetailNew(c *gin.Context) {
	req := &models.NewErpStockCommodityListReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误")
		return
	}

	list, err := req.GetDetailListNew(c)
	if err != nil {
		if err.Error() == "该商品在调拨中" {
			app.Error(c, http.StatusInternalServerError, err, err.Error())
		} else {
			app.Error(c, http.StatusInternalServerError, err, "查询失败："+err.Error())
		}
		return
	}

	app.OK(c, list, "OK")
	return
}

// DeliveryCargo 出库
// @Summary 出库
// @Tags 库存管理
// @Produce json
// @Accept json
// @Param request body DeliveryCargoReq true "出库模型"
// @Success 200 {object} app.Response
// @Router /api/v1/inventory/delivery [post]
func DeliveryCargo(c *gin.Context) {
	req := &DeliveryCargoReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		//logger.Error(err)
		app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误")
		return
	}

	if err := tools.Validate(req); err != nil {
		app.Error(c, http.StatusBadRequest, err, err.Error())
		return
	}

	err := models.SetStockCommodityState(c, req.Id)
	if err != nil {
		//logger.Error("erp stock err:", err)
		app.Error(c, http.StatusInternalServerError, err, "获取失败")
		return
	}

	app.OK(c, nil, "OK")
	return
}

// BatchPrint 批量打印
// @Summary 批量打印
// @Tags 库存管理
// @Produce json
// @Accept json
// @Param request body models.BatchPrintInfoReq true "批量打印模型"
// @Success 200 {object} app.Response
// @Router /api/v1/inventory/print [post]
func BatchPrint(c *gin.Context) {
	req := &models.BatchPrintInfoReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		//logger.Error(err)
		app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误")
		return
	}

	if err := tools.Validate(req); err != nil {
		app.Error(c, http.StatusBadRequest, err, err.Error())
		return
	}

	err := models.BatchPrint(req)
	if err != nil {
		//logger.Error("erp stock err:", err)
		app.Error(c, http.StatusInternalServerError, err, "打印失败")
		return
	}

	app.OK(c, nil, "OK")
	return
}

// BatchImport 库存导入
// @Summary 库存导入
// @Tags 库存管理
// @Produce json
// @Accept json
// @Param file body string true "上传excel文件"
// @Success 200 {object} app.Response
// @Router /api/v1/inventory/import [post]
func BatchImport(c *gin.Context) {
	models.EsStockLock.Lock()
	defer models.EsStockLock.Unlock()

	file, header, err := c.Request.FormFile("file")
	if err != nil {
		//logger.Error("form file err:", err)
		app.Error(c, http.StatusInternalServerError, err, "预览失败")
		return
	}

	readAll, err := io.ReadAll(file)
	if err != nil {
		//logger.Error("read all err:", err)
		app.Error(c, http.StatusInternalServerError, err, "预览失败")
		return
	}

	fmt.Println("header:", header.Filename)
	_, colsMap, err := models.FileExcelImport(c, readAll, nil, 3, 0)
	if err != nil {
		//logger.Error("file excel reader err:", err)
		app.Error(c, http.StatusInternalServerError, err, err.Error())
		return
	}

	fmt.Println("colsMap:", colsMap)
	if len(colsMap) != 0 {
		colsMap = colsMap[1:]
	}

	stockier := models.NewStockImporter()
	err = stockier.ImportStockData(colsMap)
	if err != nil {
		app.Error(c, http.StatusInternalServerError, err, err.Error())
		return
	}

	app.OK(c, nil, "导入成功")
	return
}

// AddRemark 添加备注
// @Summary 添加备注
// @Tags 库存管理
// @Produce json
// @Accept json
// @Param request body AddRemarkReq true "添加备注模型"
// @Success 200 {object} app.Response
// @Router /api/v1/inventory/add_remark [post]
func AddRemark(c *gin.Context) {
	req := &AddRemarkReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		//logger.Error(err)
		app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误")
		return
	}

	if err := tools.Validate(req); err != nil {
		app.Error(c, http.StatusBadRequest, err, err.Error())
		return
	}

	err := models.UpdateStockCommodityRemark(req.Id, req.Remark)
	if err != nil {
		//logger.Error("erp stock err:", err)
		app.Error(c, http.StatusInternalServerError, err, "获取失败")
		return
	}

	app.OK(c, nil, "OK")
	return
}

// QueryCode 查询商品串码或条码
// @Summary 查询商品串码或条码
// @Tags 库存管理
// @Produce json
// @Accept json
// @Param request body models.QueryCodeReq true "查询商品串码或条码模型"
// @Success 200 {object} models.QueryCodeResp
// @Router /api/v1/inventory/query_code [post]
func QueryCode(c *gin.Context) {
	req := &models.QueryCodeReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误:"+err.Error())
		return
	}

	if err := tools.Validate(req); err != nil {
		app.Error(c, http.StatusBadRequest, err, err.Error())
		return
	}

	list, err := models.GetCodeList(req)
	if err != nil {
		logger.Error("GetCodeList err:", logger.Field("err", err))
		app.Error(c, http.StatusInternalServerError, err, err.Error())
		return
	}

	app.OK(c, list, "OK")
}

// QueryName 通过名称模糊查询商品库存详情
// @Summary 通过名称模糊查询商品库存详情
// @Tags 库存管理
// @Produce json
// @Accept json
// @Param request body models.QueryNameReq true "通过名称模糊查询商品库存详情模型"
// @Success 200 {object} models.ErpStockCommodityListResp
// @Router /api/v1/inventory/query_name [post]
func QueryName(c *gin.Context) {
	req := &models.QueryNameReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		//logger.Error(err)
		app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误")
		return
	}

	var detailReq models.ErpStockCommodityListReq
	detailReq.CommodityName = append(detailReq.CommodityName, req.CommodityName)
	detailReq.PageIndex = req.PageIndex
	detailReq.PageSize = req.PageSize
	detailReq.StoreId = req.StoreId
	detailReq.State = append(detailReq.State, req.State)

	list, err := detailReq.GetDetailList(c, 2)
	if err != nil {
		//logger.Error("erp stock err:", err)
		if err.Error() == "该商品在调拨中" {
			app.Error(c, http.StatusInternalServerError, err, err.Error())
		} else {
			app.Error(c, http.StatusInternalServerError, err, "查询失败："+err.Error())
		}
		return
	}

	// 去除重复数据，相同名称只返回库存时间最久的数据
	list, err = models.RemoveDuplicates(list)
	if err != nil {
		app.Error(c, http.StatusInternalServerError, err, err.Error())
		return
	}

	app.OK(c, list, "OK")
	return
}

// ImeiTrace 串码追踪
// @Summary 串码追踪
// @Tags 库存管理
// @Produce json
// @Accept json
// @Param request body models.ImeiTraceReq true "串码追踪模型"
// @Success 200 {object} models.ImeiTraceResp
// @Router /api/v1/inventory/imei/trace [post]
func ImeiTrace(c *gin.Context) {
	req := &models.ImeiTraceReq{}
	if err := c.ShouldBindJSON(&req); err != nil {
		app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误")
		return
	}

	list, err := models.QueryImeiTraceData(req)
	if err != nil {
		app.Error(c, http.StatusInternalServerError, err, err.Error())
		return
	}

	app.OK(c, list, "OK")
	return
}
