package rest

import (
	"git.sch9.ru/new_gate/ms-tester/internal/tester"
	testerv1 "git.sch9.ru/new_gate/ms-tester/proto/tester/v1"
	"github.com/gofiber/fiber/v2"
)

type TesterHandlers struct {
	problemsUC tester.ProblemUseCase
	contestsUC tester.ContestUseCase
}

func NewTesterHandlers(problemsUC tester.ProblemUseCase, contestsUC tester.ContestRepository) *TesterHandlers {
	return &TesterHandlers{
		problemsUC: problemsUC,
		contestsUC: contestsUC,
	}
}

func (h *TesterHandlers) ListContests(c *fiber.Ctx) error {
	return c.SendStatus(fiber.StatusNotImplemented)
}

func (h *TesterHandlers) ListProblems(c *fiber.Ctx) error {
	return c.SendStatus(fiber.StatusNotImplemented)
}

func (h *TesterHandlers) CreateContest(c *fiber.Ctx) error {
	id, err := h.contestsUC.CreateContest(c.Context(), "Название контеста")
	if err != nil {
		return err
	}

	return c.JSON(testerv1.CreateContestResponse{
		Id: id,
	})
}

func (h *TesterHandlers) DeleteContest(c *fiber.Ctx, id int32) error {
	err := h.contestsUC.DeleteContest(c.Context(), id)
	if err != nil {
		return err
	}

	return c.SendStatus(fiber.StatusOK)
}

func (h *TesterHandlers) GetContest(c *fiber.Ctx, id int32) error {
	contest, err := h.contestsUC.ReadContestById(c.Context(), id)
	if err != nil {
		return err
	}

	return c.JSON(testerv1.GetContestResponse{
		Contest: testerv1.Contest{
			Id:        *contest.Id,
			Title:     *contest.Title,
			CreatedAt: *contest.CreatedAt,
			UpdatedAt: *contest.UpdatedAt,
		},
	})
}

func (h *TesterHandlers) DeleteParticipant(c *fiber.Ctx, id int32, params testerv1.DeleteParticipantParams) error {
	err := h.contestsUC.DeleteParticipant(c.Context(), params.ParticipantId)
	if err != nil {
		return err
	}

	return c.SendStatus(fiber.StatusOK)
}

func (h *TesterHandlers) AddParticipant(c *fiber.Ctx, id int32, params testerv1.AddParticipantParams) error {
	id, err := h.contestsUC.AddParticipant(c.Context(), id, params.UserId)
	if err != nil {
		return err
	}

	return c.JSON(testerv1.AddParticipantResponse{
		Id: id,
	})
}

func (h *TesterHandlers) DeleteTask(c *fiber.Ctx, id int32, params testerv1.DeleteTaskParams) error {
	err := h.contestsUC.DeleteTask(c.Context(), params.TaskId)
	if err != nil {
		return err
	}

	return c.SendStatus(fiber.StatusOK)
}

func (h *TesterHandlers) AddTask(c *fiber.Ctx, id int32, params testerv1.AddTaskParams) error {
	id, err := h.contestsUC.AddTask(c.Context(), id, params.ProblemId)
	if err != nil {
		return err
	}

	return c.SendStatus(fiber.StatusNotImplemented)
}

func (h *TesterHandlers) CreateProblem(c *fiber.Ctx) error {
	id, err := h.problemsUC.CreateProblem(c.Context(), "Название задачи")
	if err != nil {
		return err
	}

	return c.JSON(testerv1.CreateProblemResponse{
		Id: id,
	})
}

func (h *TesterHandlers) DeleteProblem(c *fiber.Ctx, id int32) error {
	err := h.problemsUC.DeleteProblem(c.Context(), id)
	if err != nil {
		return err
	}

	return c.SendStatus(fiber.StatusOK)

}

func (h *TesterHandlers) GetProblem(c *fiber.Ctx, id int32) error {
	problem, err := h.problemsUC.ReadProblemById(c.Context(), id)
	if err != nil {
		return err
	}

	return c.JSON(
		testerv1.GetProblemResponse{Problem: testerv1.Problem{
			Id:           *problem.Id,
			Legend:       *problem.Legend,
			InputFormat:  *problem.InputFormat,
			OutputFormat: *problem.OutputFormat,
			Notes:        *problem.Notes,
			Tutorial:     *problem.Tutorial,
			LatexSummary: *problem.LatexSummary,
			TimeLimit:    *problem.TimeLimit,
			MemoryLimit:  *problem.MemoryLimit,
			CreatedAt:    *problem.CreatedAt,
			UpdatedAt:    *problem.UpdatedAt,
		}},
	)
}