package services_astrologer

import (
	dto "astrology-api/dto_astrologer/activity"
	repositories "astrology-api/repositories_astrologer"
	userservices "astrology-api/services"
)

//////////////////////////////////////////////////////////////
// Activity Service
//////////////////////////////////////////////////////////////

type activityService struct {
	repository repositories.ActivityRepository
}

//////////////////////////////////////////////////////////////
// Constructor
//////////////////////////////////////////////////////////////

func NewActivityService(
	repository repositories.ActivityRepository,
) ActivityService {

	return &activityService{
		repository: repository,
	}
}

//////////////////////////////////////////////////////////////
// Add Waiting
//////////////////////////////////////////////////////////////

// The queue rules (duplicates, capacity, timeouts, FIFO hand-over) live in
// services/consultation_queue_service.go, shared with the customer's own
// /consultation/queue endpoints, so the two sides cannot disagree.
func (s *activityService) AddWaiting(astrologerUserID uint, request dto.AddWaitingRequest) error {

	_, err := userservices.AddToWaitingQueue(astrologerUserID, request.UserID, request.WaitingType)

	return err
}

//////////////////////////////////////////////////////////////
// Remove Waiting
//////////////////////////////////////////////////////////////

// RemoveWaiting takes the customer out of the queue (REJECTED) and hands the
// turn on if they held it. Only a row in this astrologer's own queue.
func (s *activityService) RemoveWaiting(astrologerUserID uint, queueID uint) error {
	return userservices.RemoveFromWaitingQueue(astrologerUserID, queueID)
}

//////////////////////////////////////////////////////////////
// Waiting List
//////////////////////////////////////////////////////////////

func (s *activityService) GetWaitingList(astrologerUserID uint, request dto.PaginationRequest) (*dto.WaitingListResponse, error) {

	astrologerID, err := userservices.AstrologerIDByUserID(astrologerUserID)

	if err != nil {
		return nil, err
	}

	// Apply any timeouts first so the list is current.
	userservices.KickWaitingQueue(astrologerID)

	list, total, err := s.repository.GetWaitingList(
		astrologerID,
		request,
	)
	if err != nil {
		return nil, err
	}
	response := dto.WaitingListResponse{
		List: list,
		Pagination: dto.PaginationResponse{
			Page:         request.Page,
			Limit:        request.Limit,
			TotalRecords: total,
			TotalPages:   int((total + int64(request.Limit) - 1) / int64(request.Limit)),
		},
	}

	return &response, nil
}

func (s *activityService) GetChatHistory(astrologerID uint, request dto.PaginationRequest) (*dto.ChatHistoryResponse, error) {
	list, total, err := s.repository.GetChatHistory(astrologerID, request)
	if err != nil {
		return nil, err
	}
	return &dto.ChatHistoryResponse{
		List: list,
		Pagination: dto.PaginationResponse{
			Page:         request.Page,
			Limit:        request.Limit,
			TotalRecords: total,
			TotalPages:   int((total + int64(request.Limit) - 1) / int64(request.Limit)),
		},
	}, nil
}

func (s *activityService) GetChatDetail(astrologerID uint, chatID uint) (*dto.ChatDetailResponse, error) {
	return s.repository.GetChatDetail(
		astrologerID,
		chatID,
	)
}

func (s *activityService) GetCallHistory(astrologerID uint, request dto.PaginationRequest) (*dto.CallHistoryResponse, error) {
	list, total, err := s.repository.GetCallHistory(
		astrologerID,
		request,
	)
	if err != nil {
		return nil, err
	}

	return &dto.CallHistoryResponse{

		List: list,

		Pagination: dto.PaginationResponse{

			Page: request.Page,

			Limit: request.Limit,

			TotalRecords: total,

			TotalPages: int((total + int64(request.Limit) - 1) / int64(request.Limit)),
		},
	}, nil
}

func (s *activityService) GetCallDetail(astrologerID uint, callID uint) (*dto.CallDetailResponse, error) {
	return s.repository.GetCallDetail(
		astrologerID,
		callID,
	)
}

func (s *activityService) GetAstromallOrders(astrologerID uint, request dto.PaginationRequest) (*dto.AstromallOrderResponse, error) {

	list, total, err := s.repository.GetAstromallOrders(
		astrologerID,
		request,
	)

	if err != nil {
		return nil, err
	}

	return &dto.AstromallOrderResponse{

		List: list,

		Pagination: dto.PaginationResponse{

			Page: request.Page,

			Limit: request.Limit,

			TotalRecords: total,

			TotalPages: int((total + int64(request.Limit) - 1) / int64(request.Limit)),
		},
	}, nil
}

func (s *activityService) GetAstromallOrderDetail(astrologerID uint, orderID uint) (*dto.AstromallOrderItem, error) {
	return s.repository.GetAstromallOrderDetail(astrologerID, orderID)
}
