package service

import (
	"web-qudo-be/app/module/schedules/mapper"
	"web-qudo-be/app/module/schedules/repository"
	"web-qudo-be/app/module/schedules/request"
	schedulesResponse "web-qudo-be/app/module/schedules/response"
	"web-qudo-be/utils/paginator"

	"github.com/google/uuid"
)

type SchedulesService interface {
	All(clientId *uuid.UUID, req request.SchedulesQueryRequest) ([]*schedulesResponse.SchedulesResponse, *paginator.Pagination, error)
	Show(clientId *uuid.UUID, id uint) (*schedulesResponse.SchedulesResponse, error)
	Save(clientId *uuid.UUID, req request.SchedulesCreateRequest) (*schedulesResponse.SchedulesResponse, error)
	Update(clientId *uuid.UUID, id uint, req request.SchedulesUpdateRequest) error
	Delete(clientId *uuid.UUID, id uint) error
	SummaryStats(clientId *uuid.UUID) (*schedulesResponse.SchedulesSummaryStats, error)
}

type schedulesService struct {
	schedulesRepository repository.SchedulesRepository
}

func NewSchedulesService(schedulesRepository repository.SchedulesRepository) SchedulesService {
	return &schedulesService{
		schedulesRepository: schedulesRepository,
	}
}

func (_i *schedulesService) All(clientId *uuid.UUID, req request.SchedulesQueryRequest) ([]*schedulesResponse.SchedulesResponse, *paginator.Pagination, error) {
	schedules, pagination, err := _i.schedulesRepository.All(clientId, req)
	if err != nil {
		return nil, nil, err
	}

	responses := mapper.ToSchedulesResponseList(schedules)
	return responses, pagination, nil
}

func (_i *schedulesService) Show(clientId *uuid.UUID, id uint) (*schedulesResponse.SchedulesResponse, error) {
	schedule, err := _i.schedulesRepository.Show(clientId, id)
	if err != nil {
		return nil, err
	}

	response := mapper.ToSchedulesResponse(schedule)
	return response, nil
}

func (_i *schedulesService) Save(clientId *uuid.UUID, req request.SchedulesCreateRequest) (*schedulesResponse.SchedulesResponse, error) {
	schedule := req.ToEntity()

	savedSchedule, err := _i.schedulesRepository.Save(clientId, schedule)
	if err != nil {
		return nil, err
	}

	response := mapper.ToSchedulesResponse(savedSchedule)
	return response, nil
}

func (_i *schedulesService) Update(clientId *uuid.UUID, id uint, req request.SchedulesUpdateRequest) error {
	schedule := req.ToEntity()

	err := _i.schedulesRepository.Update(clientId, id, schedule)
	if err != nil {
		return err
	}

	return nil
}

func (_i *schedulesService) Delete(clientId *uuid.UUID, id uint) error {
	err := _i.schedulesRepository.Delete(clientId, id)
	if err != nil {
		return err
	}

	return nil
}

func (_i *schedulesService) SummaryStats(clientId *uuid.UUID) (*schedulesResponse.SchedulesSummaryStats, error) {
	// Get today's count
	todayReq := request.SchedulesQueryRequest{}
	todayCount, err := _i.schedulesRepository.Count(clientId, todayReq)
	if err != nil {
		return nil, err
	}

	// Get this week's count
	weekReq := request.SchedulesQueryRequest{}
	weekCount, err := _i.schedulesRepository.Count(clientId, weekReq)
	if err != nil {
		return nil, err
	}

	// Get total count
	totalReq := request.SchedulesQueryRequest{}
	totalCount, err := _i.schedulesRepository.Count(clientId, totalReq)
	if err != nil {
		return nil, err
	}

	// Get live streaming count
	liveReq := request.SchedulesQueryRequest{
		IsLiveStreaming: &[]bool{true}[0],
	}
	liveCount, err := _i.schedulesRepository.Count(clientId, liveReq)
	if err != nil {
		return nil, err
	}

	// Get upcoming count (start_date > today)
	upcomingReq := request.SchedulesQueryRequest{}
	upcomingCount, err := _i.schedulesRepository.Count(clientId, upcomingReq)
	if err != nil {
		return nil, err
	}

	stats := &schedulesResponse.SchedulesSummaryStats{
		TotalToday:    int(todayCount),
		TotalThisWeek: int(weekCount),
		TotalAll:      int(totalCount),
		TotalLive:     int(liveCount),
		TotalUpcoming: int(upcomingCount),
	}

	return stats, nil
}
