package handlers

import (
	"net/http"
	"sort"

	"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_process_route_to_routes(e *echo.Echo) {
	group := e.Group("/processRoute")
	group.Use(middleware.AuthMiddleware)
	group.POST("/getPage", processRouteGetPage)
	group.POST("/getList", processRouteGetList)
	group.POST("/save", processRouteSave)
	group.POST("/update", processRouteUpdate)
	group.POST("/remove", processRouteRemove)
	group.POST("/upgrade", processRouteUpgrade)
	group.POST("/regrade", processRouteRegrade)

}

func processRouteGetPage(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.ProcessRoute{})
	if err != nil {
		utils.PrintSqlErr(err)
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
	}
	list := utils.ConvertInterface[[]models.ProcessRoute](result.Records)
	if len(list) == 0 {
		list = []models.ProcessRoute{}
	}
	for i := range list {
		model := list[i]
		minioList, err := services.JdbcClient.GetMinioFile(model)
		if err != nil {
			utils.PrintSearchFileErr(err)
		}
		model.FileList = &minioList

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

		for j := range detail_list {
			detail := detail_list[j]

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

			detail.ProcessStage = stage

			detail_list[j] = detail
		}
		model.DetailList = &detail_list

		routeParam := new(models.ProcessRoute)
		routeParam.ParentId = model.ID
		count, err := services.JdbcClient.GetJdbcCount(routeParam)
		if err != nil {
			utils.PrintSqlErr(err)
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
		}
		if count > 0 {
			isHaveHistory := models.Common_Value_True_Value
			model.IsHaveHistory = &isHaveHistory
		} else {
			isHaveHistory := models.Common_Value_False_Value
			model.IsHaveHistory = &isHaveHistory
		}

		if model.InspectProgramId != nil && len(*model.InspectProgramId) > 0 {
			inspectProgram := new(models.QualityInspectProgram)
			inspectProgram.ID = model.InspectProgramId
			err = services.JdbcClient.GetJdbcModelById(inspectProgram)
			if err != nil {
				utils.PrintSqlErr(err)
				return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
			}
			model.InspectProgram = inspectProgram
		}

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

}

func processRouteGetList(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.ProcessRoute{})
	if err != nil {
		utils.PrintSqlErr(err)
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
	}
	list := utils.ConvertInterface[[]models.ProcessRoute](result)
	if len(list) == 0 {
		return c.JSON(http.StatusOK, []string{})
	}
	return c.JSON(http.StatusOK, list)
}

func processRouteSave(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("用户请先登录", ""))
	}
	route := new(models.ProcessRoute)
	if err := c.Bind(route); err != nil {
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("参数解析失败", err.Error()))
	}
	err_msg := processRoute_generateCode(route, tx)
	if err_msg != "" {
		tx.Rollback()
		return c.JSON(http.StatusBadRequest, utils.ErrorResponse(err_msg, ""))
	}

	status := models.Status_Enable
	route.Status = &status
	route.CreateId = &user_id
	parentId := models.Common_Value_Zero_String
	route.ParentId = &parentId
	services.JdbcClient.JdbcInsert(route, tx)

	detail_list := *route.DetailList
	for _, detail := range detail_list {
		detail.RouteId = route.ID
		err := services.JdbcClient.JdbcInsert(&detail, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			tx.Rollback()
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
		}
	}

	if route.FileList == nil {
		tx.Commit()
		return c.JSON(http.StatusOK, route)
	}
	fileList := *route.FileList
	for _, file := range fileList {
		file.RefId = route.ID
		refType := models.File_Ref_Type_Process_Route
		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, route)

}

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

	route := new(models.ProcessRoute)
	if err := c.Bind(route); 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("用户请先登录", ""))
	}
	route.UpdateId = &user_id
	err := services.JdbcClient.JdbcUpdateById(route, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		tx.Rollback()
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
	}

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

	detail_list := *route.DetailList
	for _, detail := range detail_list {
		detail.RouteId = route.ID
		err := services.JdbcClient.JdbcInsert(&detail, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			tx.Rollback()
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
		}
	}

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

	fileList := *route.FileList
	for _, file := range fileList {
		file.RefId = route.ID
		refType := models.File_Ref_Type_Process_Route
		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, route)
}

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

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

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

	minio_file := new(models.MinioFile)
	minio_file.RefId = route.ID
	refType := models.File_Ref_Type_Process_Route
	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("系统错误", ""))
	}

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

	history := new(models.ProcessRoute)
	history.ParentId = route.ID
	history_result, _ := services.JdbcClient.GetJdbcListByObject(history, tx)
	history_list := utils.ConvertInterface[[]models.ProcessRoute](history_result)
	for _, history := range history_list {
		err := services.JdbcClient.JdbcRemoveById(history, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			tx.Rollback()
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
		}

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

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

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

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

	sess, _ := session.Get("auth_session", c)
	user_id, ok := sess.Values["user_id"].(int64)
	if !ok {
		return c.JSON(http.StatusBadRequest, utils.ErrorResponse("用户请先登录", ""))
	}
	err_msg := processRoute_generateCode(route, tx)
	if err_msg != "" {
		tx.Rollback()
		return c.JSON(http.StatusBadRequest, utils.ErrorResponse(err_msg, ""))
	}
	route.ID = nil
	status := models.Status_Enable
	route.Status = &status
	route.CreateId = &user_id
	parentId := models.Common_Value_Zero_String
	route.ParentId = &parentId
	err := services.JdbcClient.JdbcInsert(route, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		tx.Rollback()
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
	}

	exist_route := new(models.ProcessRoute)
	exist_route.ID = old_uuid
	exist_route.ParentId = route.ID
	status = models.Status_Disable
	exist_route.Status = &status
	exist_route.UpdateId = &user_id
	err = services.JdbcClient.JdbcUpdateById(exist_route, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		tx.Rollback()
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
	}

	child_route := new(models.ProcessRoute)
	child_route.ParentId = route.ID
	child_route.UpdateId = &user_id
	var paramMap = map[string]interface{}{
		"parentId": old_uuid,
	}
	err = services.JdbcClient.JdbcUpdate(child_route, paramMap, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		tx.Rollback()
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
	}

	detail_list := *route.DetailList
	for _, detail := range detail_list {
		detail.RouteId = route.ID
		err := services.JdbcClient.JdbcInsert(&detail, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			tx.Rollback()
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
		}
	}

	if route.FileList == nil {
		tx.Commit()
		return c.JSON(http.StatusOK, route)
	}
	fileList := *route.FileList
	for _, file := range fileList {
		file.RefId = route.ID
		refType := models.File_Ref_Type_Process_Route
		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, route)
}

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

	route := new(models.ProcessRoute)
	if err := c.Bind(route); err != nil {
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("参数解析失败", err.Error()))
	}
	children := new(models.ProcessRoute)
	children.ParentId = route.ID
	result, err := services.JdbcClient.GetJdbcListByObject(children, tx)
	if err != nil {
		utils.PrintSqlErr(err)
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", err.Error()))
	}
	children_list := utils.ConvertInterface[[]models.ProcessRoute](result)

	sess, _ := session.Get("auth_session", c)
	user_id, ok := sess.Values["user_id"].(int64)
	if !ok {
		return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("用户请先登录", ""))
	}
	if len(children_list) > 0 {
		//倒序
		sort.Slice(children_list, func(i, j int) bool {
			return *children_list[i].CreateTime > *children_list[j].CreateTime
		})

		child := &children_list[0]
		parentId := models.Common_Value_Zero_String
		child.ParentId = &parentId
		status := models.Status_Enable
		child.Status = &status
		child.UpdateId = &user_id
		err := services.JdbcClient.JdbcUpdateById(child, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			tx.Rollback()
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
		}

		children = new(models.ProcessRoute)
		children.ParentId = child.ID
		paramMap := map[string]interface{}{
			"parentId": route.ID,
		}
		children.UpdateId = &user_id
		err = services.JdbcClient.JdbcUpdate(children, paramMap, tx)
		if err != nil {
			utils.PrintSqlErr(err)
			tx.Rollback()
			return c.JSON(http.StatusInternalServerError, utils.ErrorResponse("系统错误", ""))
		}

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

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

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

func processRoute_generateCode(model *models.ProcessRoute, 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.ProcessRoute)
		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_Process_Route, *model.TenantId, tx)
			if err != nil {
				return "自动生成编码失败"
			}
			modelParam := new(models.ProcessRoute)
			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 ""
}
