package handlers

import (
	"net/http"

	"easydo-echo_win7/models"
	"easydo-echo_win7/services"
	"easydo-echo_win7/utils"

	"easydo-echo_win7/middleware"

	"github.com/jmoiron/sqlx"
	"github.com/labstack/echo-contrib/session"
	"github.com/labstack/echo/v4"
)

func Add_product_plan_to_routes(e *echo.Echo) {
	group := e.Group("/productPlan")
	group.Use(middleware.AuthMiddleware)
	group.POST("/getPage", productPlanGetPage)
	group.POST("/getList", productPlanGetList)
	group.POST("/save", productPlanSave)
	group.POST("/update", productPlanUpdate)
	group.POST("/remove", productPlanRemove)
}

func productPlanGetPage(c echo.Context) error {
	var paramMap map[string]interface{}
	if err := c.Bind(&paramMap); err != nil {
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("参数解析失败", err.Error()))
	}
	result, err := services.JdbcClient.GetJdbcPage(paramMap, models.ProductPlan{})
	if err != nil {
		utils.PrintSqlErr(err)
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
	}
	list := utils.ConvertInterface[[]models.ProductPlan](result.Records)
	if len(list) == 0 {
		list = []models.ProductPlan{}
	}
	for i := range list {
		model := list[i]
		minioList, err := services.JdbcClient.GetMinioFile(model)
		if err != nil {
			utils.PrintSearchFileErr(err)
		}
		model.FileList = &minioList

		sale_order := new(models.SaleOrder)
		sale_order.ID = model.SaleOrderId
		err = services.JdbcClient.GetJdbcModelById(sale_order)
		if err != nil {
			utils.PrintSqlErr(err)
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
		}
		model.SaleOrder = sale_order

		saleOrder_minioList, err := services.JdbcClient.GetMinioFile(sale_order)
		if err != nil {
			utils.PrintSearchFileErr(err)
		}
		sale_order.FileList = &saleOrder_minioList

		saleOrder_detailParam := new(models.SaleOrderDetail)
		saleOrder_detailParam.OrderId = sale_order.ID
		saleOrder_result, err := services.JdbcClient.GetJdbcListByObject(saleOrder_detailParam)
		if err != nil {
			utils.PrintSqlErr(err)
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
		}
		saleOrder_detailList := utils.ConvertInterface[[]models.SaleOrderDetail](saleOrder_result)
		for j := range saleOrder_detailList {
			detail := saleOrder_detailList[j]

			material := new(models.ProductMaterial)
			material.Code = detail.MaterialCode
			err = services.JdbcClient.GetJdbcModel(material)
			if err != nil {
				utils.PrintSqlErr(err)
				return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
			}
			detail.Material = material
			
			saleOrder_detailList[j] = detail
		}
		sale_order.ChildrenList = &saleOrder_detailList

		bomParam := new(models.ProductPlanBom)
		bomParam.PlanId = model.ID
		result, err := services.JdbcClient.GetJdbcListByObject(bomParam)
		if err != nil {
			utils.PrintSqlErr(err)
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
		}
		bom_list := utils.ConvertInterface[[]models.ProductPlanBom](result)

		for j := range bom_list {
			plan_bom := bom_list[j]

			route := new(models.ProcessRoute)
			route.ID = plan_bom.RouteId
			err = services.JdbcClient.GetJdbcModelById(route)
			if err != nil {
				utils.PrintSqlErr(err)
				return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
			}
			plan_bom.ProcessRoute = route

			inspect_program := new(models.QualityInspectProgram)
			inspect_program.ID = plan_bom.InspectProgramId
			err = services.JdbcClient.GetJdbcModelById(inspect_program)
			if err != nil {
				utils.PrintSqlErr(err)
				return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
			}
			plan_bom.QualityInspectProgram = inspect_program

			bom := new(models.ProductBom)
			bom.ID = plan_bom.BomId
			err = services.JdbcClient.GetJdbcModelById(bom)
			if err != nil {
				utils.PrintSqlErr(err)
				return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
			}
			plan_bom.ProductBom = bom

			bom_list[j] = plan_bom
		}
		model.BomList = &bom_list

		deviceParam := new(models.ProductPlanDevice)
		deviceParam.PlanId = model.ID
		device_result, err := services.JdbcClient.GetJdbcListByObject(deviceParam)
		if err != nil {
			utils.PrintSqlErr(err)
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
		}
		device_list := utils.ConvertInterface[[]models.ProductPlanDevice](device_result)

		for j := range device_list {
			plan_device := device_list[j]

			device := new(models.Device)
			device.ID = plan_device.DeviceId
			err = services.JdbcClient.GetJdbcModelById(device)
			if err != nil {
				utils.PrintSqlErr(err)
				return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
			}
			plan_device.Device = device

			device_list[j] = plan_device
		}

		userParam := new(models.ProductPlanUser)
		userParam.PlanId = model.ID
		user_result, err := services.JdbcClient.GetJdbcListByObject(userParam)
		if err != nil {
			utils.PrintSqlErr(err)
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
		}
		user_list := utils.ConvertInterface[[]models.ProductPlanUser](user_result)

		for j := range user_list {
			plan_user := user_list[j]

			user := new(models.SysUser)
			user.ID = plan_user.UserId
			err = services.JdbcClient.GetJdbcModelById(user)
			if err != nil {
				utils.PrintSqlErr(err)
				return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
			}
			plan_user.User = user

			user_list[j] = plan_user
		}

		list[i] = model
	}
	result.Records = list
	return c.JSON(http.StatusOK, result)

}

func productPlanGetList(c echo.Context) error {
	var paramMap map[string]interface{}
	if err := c.Bind(&paramMap); err != nil {
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("参数解析失败", err.Error()))
	}
	result, err := services.JdbcClient.GetJdbcList(paramMap, models.ProductPlan{})
	if err != nil {
		utils.PrintSqlErr(err)
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
	}
	list := utils.ConvertInterface[[]models.ProductPlan](result)
	if len(list) == 0 {
		return c.JSON(http.StatusOK, []string{})
	}
	return c.JSON(http.StatusOK, list)
}

func productPlanSave(c echo.Context) error {
	tx, _ := services.MYSQL_DB.Beginx()

	sess, _ := session.Get("auth_session", c)
	user_id, ok := sess.Values["user_id"].(int64)
	if !ok {
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("用户请先登录", ""))
	}
	plan := new(models.ProductPlan)
	if err := c.Bind(plan); err != nil {
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("参数解析失败", err.Error()))
	}
	err_msg := productPlan_generateCode(plan, tx)
	if err_msg != "" {
		tx.Rollback()
		return c.JSON(http.StatusBadRequest, utils.ErrorResponse(err_msg, ""))
	}
	status := models.Product_Plan_Status_Pending
	plan.Status = &status
	plan.CreateId = &user_id
	err := services.JdbcClient.JdbcInsert(plan, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		tx.Rollback()
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
	}

	bom_list := *plan.BomList
	for _, detail := range bom_list {
		detail.PlanId = plan.ID
		err := services.JdbcClient.JdbcInsert(&detail, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			tx.Rollback()
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
		}
	}
	device_list := *plan.DeviceList
	for _, detail := range device_list {
		detail.PlanId = plan.ID
		err := services.JdbcClient.JdbcInsert(&detail, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			tx.Rollback()
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
		}
	}
	user_list := *plan.UserList
	for _, detail := range user_list {
		detail.PlanId = plan.ID
		err := services.JdbcClient.JdbcInsert(&detail, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			tx.Rollback()
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
		}
	}

	if plan.FileList == nil {
		tx.Commit()
		return c.JSON(http.StatusOK, plan)
	}
	fileList := *plan.FileList
	for _, file := range fileList {
		file.RefId = plan.ID
		refType := models.File_Ref_Type_Product_Plan
		file.RefType = &refType

		err := services.JdbcClient.JdbcInsert(&file, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			tx.Rollback()
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
		}
	}
	tx.Commit()
	return c.JSON(http.StatusOK, plan)

}

func productPlanUpdate(c echo.Context) error {
	tx, _ := services.MYSQL_DB.Beginx()

	plan := new(models.ProductPlan)
	if err := c.Bind(plan); err != nil {
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("参数解析失败", err.Error()))
	}
	sess, _ := session.Get("auth_session", c)
	user_id, ok := sess.Values["user_id"].(int64)
	if !ok {
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("用户请先登录", ""))
	}
	plan.UpdateId = &user_id
	err := services.JdbcClient.JdbcUpdateById(plan, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		tx.Rollback()
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
	}

	plan_bom := new(models.ProductPlanBom)
	plan_bom.PlanId = plan.ID
	err = services.JdbcClient.JdbcRemove(plan_bom, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		tx.Rollback()
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
	}
	bom_list := *plan.BomList
	for _, detail := range bom_list {
		detail.PlanId = plan.ID
		err := services.JdbcClient.JdbcInsert(&detail, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			tx.Rollback()
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
		}
	}

	plan_device := new(models.ProductPlanDevice)
	plan_device.PlanId = plan.ID
	err = services.JdbcClient.JdbcRemove(plan_device, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		tx.Rollback()
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
	}
	device_list := *plan.DeviceList
	for _, detail := range device_list {
		detail.PlanId = plan.ID
		err := services.JdbcClient.JdbcInsert(&detail, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			tx.Rollback()
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
		}
	}

	plan_user := new(models.ProductPlanUser)
	plan_user.PlanId = plan.ID
	err = services.JdbcClient.JdbcRemove(plan_user, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		tx.Rollback()
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
	}
	user_list := *plan.UserList
	for _, detail := range user_list {
		detail.PlanId = plan.ID
		err := services.JdbcClient.JdbcInsert(&detail, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			tx.Rollback()
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
		}
	}

	if plan.FileList == nil {
		tx.Commit()
		return c.JSON(http.StatusOK, plan)
	}

	fileList := *plan.FileList
	for _, file := range fileList {
		file.RefId = plan.ID
		refType := models.File_Ref_Type_Product_Plan
		file.RefType = &refType

		err := services.JdbcClient.JdbcInsert(&file, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			tx.Rollback()
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
		}
	}

	tx.Commit()
	return c.JSON(http.StatusOK, plan)
}

func productPlanRemove(c echo.Context) error {
	tx, _ := services.MYSQL_DB.Beginx()

	plan := new(models.ProductPlan)
	if err := c.Bind(plan); err != nil {
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("参数解析失败", err.Error()))
	}

	err := services.JdbcClient.JdbcRemoveById(plan, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		tx.Rollback()
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
	}

	minio_file := new(models.MinioFile)
	minio_file.RefId = plan.ID
	refType := models.File_Ref_Type_Product_Plan
	minio_file.RefType = &refType
	err = services.JdbcClient.JdbcRemove(minio_file, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		tx.Rollback()
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
	}

	plan_bom := new(models.ProductPlanBom)
	plan_bom.PlanId = plan.ID
	err = services.JdbcClient.JdbcRemove(plan_bom, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		tx.Rollback()
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
	}

	plan_device := new(models.ProductPlanDevice)
	plan_device.PlanId = plan.ID
	err = services.JdbcClient.JdbcRemove(plan_device, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		tx.Rollback()
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
	}

	plan_user := new(models.ProductPlanUser)
	plan_user.PlanId = plan.ID
	err = services.JdbcClient.JdbcRemove(plan_user, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		tx.Rollback()
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
	}

	tx.Commit()
	return c.JSON(http.StatusOK, plan)
}

func productPlan_generateCode(model *models.ProductPlan, tx *sqlx.Tx) string {
	sync := new(models.Synchronized)
	sync.Sync.Lock()
	defer sync.Sync.Unlock()

	if model.Code != nil && len(*model.Code) > 0 {
		modelParam := new(models.ProductPlan)
		modelParam.Code = model.Code
		modelParam.TenantId = model.TenantId
		count, err := services.JdbcClient.GetJdbcCount(modelParam, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			return "SQL执行失败"
		}
		if count > 0 {
			return "编号已存在，请重新填写"
		}
	} else {
		for {
			code, err := services.GetFlowNo(models.Flow_No_Type_Product_Plan, *model.TenantId, tx)
			if err != nil {
				return "自动生成编码失败"
			}
			modelParam := new(models.ProductPlan)
			modelParam.Code = &code
			modelParam.TenantId = model.TenantId
			count, err := services.JdbcClient.GetJdbcCount(modelParam, tx)
			if err != nil {
				utils.PrintSqlErr(err)
				return "SQL执行失败"
			}
			if count == 0 {
				model.Code = &code
				break
			}
		}

	}
	return ""
}
