package control

import (
	"jannex/robot-control-manager/modules/cache"
	"jannex/robot-control-manager/modules/logger"
	"jannex/robot-control-manager/modules/request"
	"jannex/robot-control-manager/modules/robot"
	"jannex/robot-control-manager/modules/structs"
	"jannex/robot-control-manager/modules/utils"
	"time"

	"git.ex.umbach.dev/Alex/roese-utils/rslogger"
	"git.ex.umbach.dev/Alex/roese-utils/rsutils"
	"github.com/gofiber/fiber/v2"
	"github.com/rs/zerolog/log"
)

func ControlRex(c *fiber.Ctx) error {
	// swagger:operation POST /control/1 control controlRex
	// ---
	// summary: Control Rex.
	// description: |
	//   This is used to control Rex.
	// consumes:
	// - application/json
	// produces:
	// - application/json
	// parameters:
	// - in: body
	//   name: body
	//   description: Control Rex body.
	//   required: true
	//   schema:
	//     "$ref": "#/definitions/ControlBody"
	// responses:
	//   "200":
	//    description: Control Rex
	//   "400":
	//    description: Invalid request body
	//   "422":
	//    description: Robot not found

	var body structs.ControlBody

	if err := rsutils.BodyParserHelper(c, &body); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	/*
		if body.Task.Y == nil {
			fmt.Println("y not sent")
		} else {
			fmt.Printf("y-value: %d\n", *body.Task.Y)
		} */

	r := cache.GetRobotByName(body.RobotName)

	if r == nil {
		return c.SendStatus(fiber.StatusUnprocessableEntity)
	}

	if r.Status == utils.RobotStatusOffline {
		return c.JSON(structs.StatusResponse{Status: utils.ResponseStatusOffline})
	}

	if r.Status != utils.RobotStatusIdle &&
		r.Status != utils.RobotStatusRunning &&
		r.Status != utils.RobotStatusWaiting {
		return c.JSON(structs.StatusResponse{Status: utils.ResponseStatusError})
	}

	robot.ProcessJobTask(r, body.JobId, body.JobName)
	robot.UpdateRobotStatus(r, utils.RobotStatusRunning)

	r.LastTaskAt = time.Now()

	logger.AddRobotLog(rslogger.LogTypeInfo, utils.RobotTypeRex, r.Id, "Control robot with task: %v", rsutils.MarshalJson(body.Task))

	if err := request.Request(fiber.MethodPost, r.Address+":5000/api/v1/control", body.Task); err != nil {
		return c.JSON(structs.StatusResponse{Status: utils.ResponseStatusError})
	}

	robot.UpdateRobotStatus(r, utils.RobotStatusWaiting)

	return c.JSON(structs.StatusResponse{Status: utils.ResponseStatusOk})
}

func FinishControlRex(c *fiber.Ctx) error {
	// swagger:operation POST /control/1/finish control finishControlRex
	// ---
	// summary: Finish control Rex.
	// description: |
	//   This is used to finish control Rex.
	// consumes:
	// - application/json
	// produces:
	// - application/json
	// responses:
	//   "200":
	//    description: Finish control Rex
	//   "400":
	//    description: Invalid robot name
	//   "422":
	//    description: Robot not found

	var body structs.RobotFinishBody

	if err := rsutils.BodyParserHelper(c, &body); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	r := cache.GetRobotByName(body.RobotName)

	if r == nil || r.CurrentJobId != body.JobId {
		return c.SendStatus(fiber.StatusUnprocessableEntity)
	}

	lastJobName := r.CurrentJobName

	robot.UpdateRobotCurrentJob(r, "", "")
	robot.CountDownJobsWaiting(r)
	robot.UpdateRobotStatus(r, utils.RobotStatusIdle)

	log.Info().Msgf("finish %v %v", body, r)

	logger.AddRobotLog(rslogger.LogTypeInfo, utils.RobotTypeRex, r.Id, "------ Finished job id: %s name: %s ------", body.JobId, lastJobName)

	return c.SendStatus(fiber.StatusOK)
}
