package basic

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

type CreateCategoryRequest struct {
	Name string `json:"name" validate:"required"` //名称
	Pid  uint32 `json:"pid"`                      //父分类id
}

// CreateCategory 创建分类
// @Summary 创建分类
// @Tags 商品分类
// @Produce json
// @Accept json
// @Param request body CreateCategoryRequest true "商品分类创建模型"
// @Success 200 {object} app.Response
// @Router /api/v1/category/create [post]
func CreateCategory(c *gin.Context) {
	var req = new(CreateCategoryRequest)

	if err := c.ShouldBindJSON(req); err != nil {
		fmt.Println(err.Error())
		app.Error(c, 400, err, err.Error())
		return
	}

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

	if models.IsExistingCategory(req.Name) {
		app.Error(c, http.StatusBadRequest, errors.New("分类名称已存在，不能重复"), "分类名称已存在，不能重复")
		return
	}

	category := models.Category{
		Name:                  req.Name,
		Display:               1,
		Pid:                   req.Pid,
		CooperativeBusinessId: middleware.GetCooperativeBusinessId(c),
	}

	err = orm.Eloquent.Debug().Create(&category).Error
	if err != nil {
		logger.Error("创建分类失败", logger.Field("category", category), logger.Field("err", err))
		app.Error(c, 500, err, "创建分类失败")
		return
	}

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

type UpdateCategoryRequest struct {
	CreateCategoryRequest
	Id uint32 `json:"id" validate:"required"` //分类id
}

// UpdateCategory 编辑分类
// @Summary 编辑分类
// @Tags 商品分类
// @Produce json
// @Accept json
// @Param request body UpdateCategoryRequest true "商品分类编辑模型"
// @Success 200 {object} models.Category
// @Router /api/v1/category/update [post]
func UpdateCategory(c *gin.Context) {
	req := new(UpdateCategoryRequest)

	if err := c.ShouldBindJSON(req); err != nil {
		app.Error(c, 400, err, err.Error())
		return
	}

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

	old, err := models.GetCategoryById(req.Id)
	if err != nil {
		app.Error(c, 500, err, err.Error())
		logger.Error("GetCategoryById err", logger.Field("req", req), logger.Field("err", err))
		return
	}

	var category = models.Category{
		Name: req.Name,
		Pid:  req.Pid,
	}
	category.ID = old.ID

	//修改分类后需要同步修改编号
	if old.Pid != category.Pid {
		category.Number, err = models.GenerateNumber(old.CooperativeBusinessId, req.Pid)
		if err != nil {
			app.Error(c, 500, err, err.Error())
			logger.Error("GenerateNumber err", logger.Field("req", req), logger.Field("err", err))
			return
		}
	}

	err = orm.Eloquent.Model(category).Updates(category).Error
	if err != nil {
		app.Error(c, 500, err, "更新失败")
		logger.Error("GenerateNumber err", logger.Field("category", category), logger.Field("err", err))
		return
	}

	app.OK(c, category, "ok")
	return
}

type DeleteCategoryRequest struct {
	CategoryId uint32 `json:"category_id" binding:"required"`
}

// DeleteCategory 删除分类
// @Summary 删除分类
// @Tags 商品分类
// @Produce json
// @Param request body  DeleteCategoryRequest true "删除分类请求模型"
// @Success 200 {object} app.Response
// @Router /api/v1/category/delete [post]
func DeleteCategory(c *gin.Context) {
	//id := c.Param("id")
	//err := orm.Eloquent.Model(models.Category{}).
	//	Scopes(common.ScopeBusiness(middleware.GetCooperativeBusinessId(c))).
	//	Delete(id).
	//	Error
	//if err != nil {
	//	app.Error(c, 500, err, "删除失败")
	//	return
	//}

	var req = new(DeleteCategoryRequest)

	if err := c.ShouldBindJSON(&req); err != nil {
		//logger.Error(err)
		app.Error(c, http.StatusBadRequest, err, "参数错误")
		return
	}

	// 删除分类之前需要判断该分类下是否有商品
	if models.CheckCommodityByCategory(req.CategoryId) {
		app.Error(c, http.StatusBadRequest, errors.New("该分类或其子分类下有商品未删除"), "该分类或其子分类下有商品未删除")
		return
	}

	err := orm.Eloquent.Where("id=?", req.CategoryId).Delete(&models.Category{}).Error
	if err != nil {
		//logger.Error("erp commodity err:", err)
		app.Error(c, http.StatusInternalServerError, err, "删除失败")
		return
	}

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

type CategoryListRequest struct {
	IsAll bool `json:"is_all"` //是否展示全部
}

// CategoryList 分类列表
// @Summary 分类列表
// @Tags 商品分类
// @Produce json
// @Param request body  CategoryListRequest true "分类列表请求模型"
// @Success 200 {array} models.CategoryModel
// @Router /api/v1/category/list [post]
func CategoryList(c *gin.Context) {
	req := new(CategoryListRequest)
	_ = c.ShouldBindJSON(req)
	list, err := models.GetCategoryList(middleware.GetCooperativeBusinessId(c), req.IsAll)
	if err != nil {
		app.Error(c, 500, err, "获取列表失败")
		return
	}

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

type CategoryDisplayRequest struct {
	Id      uint32 `json:"id"`      //分类id
	Display int    `json:"display"` //是否展示 1展示 0隐藏
}

// CategoryDisplay 隐藏或展示分类
// @Summary 隐藏或展示分类
// @Tags 商品分类
// @Produce json
// @Param request body  CategoryDisplayRequest true "隐藏或展示分类请求模型"
// @Success 200 {object} app.Response
// @Router /api/v1/category/display [post]
func CategoryDisplay(c *gin.Context) {
	req := new(CategoryDisplayRequest)
	_ = c.ShouldBindJSON(req)

	var category models.Category
	err := orm.Eloquent.Model(models.Category{}).
		Where("id", req.Id).Find(&category).Error
	if err != nil {
		app.Error(c, 500, err, "修改失败")
		return
	}

	// 批量更新，如果父类被修改，其子类也要对应修改
	err = orm.Eloquent.Debug().Model(models.Category{}).
		Where("number like ?", category.Number+"%").
		UpdateColumn("display", req.Display).Error

	if err != nil {
		app.Error(c, 500, err, "修改失败")
		return
	}

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

// CategoryImportView 导入商品分类预览
// @Summary 导入商品分类预览
// @Tags 商品分类
// @Produce json
// @Accept json
// @Param file body string true "上传excel文件"
// @Success 200 {array} models.CategoryExcel
// @Router /api/v1/category/import_category_view [post]
func CategoryImportView(c *gin.Context) {
	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.FileExcelReader([]byte(readAll), nil)
	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:]
	}

	app.OK(c, &colsMap, "")
	return
}

// CategoryImport 导入商品分类
// @Summary 导入商品分类
// @Tags 商品分类
// @Produce json
// @Accept json
// @Param file body string true "上传excel文件"
// @Success 200  {object} app.Response
// @Router /api/v1/category/import_category [post]
func CategoryImport(c *gin.Context) {
	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, []byte(readAll), nil, 1, 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:]
	}

	err = models.ImportCategoryData(colsMap, middleware.GetCooperativeBusinessId(c))
	if err != nil {
		//logger.Error("file excel reader err:", err)
		app.Error(c, http.StatusInternalServerError, err, err.Error())
		return
	}

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