package statistic

import (
	"gitea.pena/SQuiz/common/dal"
	"gitea.pena/SQuiz/common/repository/statistics"
	"github.com/gofiber/fiber/v2"
	"strconv"
)

type Deps struct {
	DAL   *dal.DAL
	ChDAL *dal.ClickHouseDAL
}

type Statistic struct {
	dal   *dal.DAL
	chDAL *dal.ClickHouseDAL
}

func NewStatisticController(deps Deps) *Statistic {
	return &Statistic{
		dal:   deps.DAL,
		chDAL: deps.ChDAL,
	}
}

type DeviceStatReq struct {
	From uint64 // временные границы выбора статистики
	To   uint64
}

func (r *Statistic) GetDeviceStatistics(ctx *fiber.Ctx) error {
	quizIDStr := ctx.Params("quizID")

	quizID, err := strconv.ParseInt(quizIDStr, 10, 64)
	if err != nil {
		return ctx.Status(fiber.StatusBadRequest).SendString("Invalid quiz ID format")
	}

	var req DeviceStatReq
	if err := ctx.BodyParser(&req); err != nil {
		return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
	}

	deviceStats, err := r.dal.StatisticsRepo.GetDeviceStatistics(ctx.Context(), statistics.DeviceStatReq{
		QuizId: quizID,
		From:   req.From,
		To:     req.To,
	})
	if err != nil {
		return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
	}

	return ctx.Status(fiber.StatusOK).JSON(deviceStats)
}

type GeneralStatsResp struct {
	Open, Result, AvTime, Conversion map[uint64]uint64
}

func (r *Statistic) GetGeneralStatistics(ctx *fiber.Ctx) error {
	quizIDStr := ctx.Params("quizID")
	quizID, err := strconv.ParseInt(quizIDStr, 10, 64)
	if err != nil {
		return ctx.Status(fiber.StatusBadRequest).SendString("Invalid quiz ID format")
	}

	var req DeviceStatReq
	if err := ctx.BodyParser(&req); err != nil {
		return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
	}

	generalStats, err := r.dal.StatisticsRepo.GetGeneralStatistics(ctx.Context(), statistics.DeviceStatReq{
		QuizId: quizID,
		From:   req.From,
		To:     req.To,
	})
	if err != nil {
		return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
	}

	return ctx.Status(fiber.StatusOK).JSON(generalStats)
}

func (r *Statistic) GetQuestionsStatistics(ctx *fiber.Ctx) error {
	quizIDStr := ctx.Params("quizID")
	quizID, err := strconv.ParseInt(quizIDStr, 0, 64)
	if err != nil {
		return ctx.Status(fiber.StatusBadRequest).SendString("Invalid quiz ID format")
	}

	var req DeviceStatReq
	if err := ctx.BodyParser(&req); err != nil {
		return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
	}

	questionsStats, err := r.dal.StatisticsRepo.GetQuestionsStatistics(ctx.Context(), statistics.DeviceStatReq{
		QuizId: quizID,
		From:   req.From,
		To:     req.To,
	})
	if err != nil {
		return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
	}

	return ctx.Status(fiber.StatusOK).JSON(questionsStats)
}

type StatisticReq struct {
	From, To uint64 // временные границы выбора статистики
}

func (r *Statistic) AllServiceStatistics(ctx *fiber.Ctx) error {
	var req StatisticReq
	if err := ctx.BodyParser(&req); err != nil {
		return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
	}

	allSvcStats, err := r.dal.StatisticsRepo.AllServiceStatistics(ctx.Context(), req.From, req.To)
	if err != nil {
		return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
	}

	return ctx.Status(fiber.StatusOK).JSON(allSvcStats)
}

func (r *Statistic) GetPipelinesStatistics(ctx *fiber.Ctx) error {
	var req StatisticReq
	if err := ctx.BodyParser(&req); err != nil {
		return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
	}

	quizIDStr := ctx.Params("quizID")
	quizID, err := strconv.ParseInt(quizIDStr, 10, 64)
	if err != nil {
		return ctx.Status(fiber.StatusBadRequest).SendString("Invalid quiz ID format")
	}

	result, err := r.chDAL.StatisticClickRepo.GetPipelinesStatistics(ctx.Context(), quizID, req.From, req.To)
	if err != nil {
		return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
	}
	return ctx.Status(fiber.StatusOK).JSON(result)
}
