package service

import (
	"strings"
	"time"

	"nex/backend/internal/domain"
	"nex/backend/internal/repository"
)

type statsService struct {
	statsRepo repository.StatsRepository
	buffer    *StatsBuffer
}

func NewStatsService(statsRepo repository.StatsRepository, buffer *StatsBuffer) StatsService {
	return &statsService{statsRepo: statsRepo, buffer: buffer}
}

func (s *statsService) Record(providerID, modelName string) error {
	s.buffer.Increment(providerID, modelName)
	return nil
}

func (s *statsService) Get(providerID, modelName string, startDate, endDate *time.Time) ([]domain.UsageStats, error) {
	return s.statsRepo.Query(providerID, modelName, startDate, endDate)
}

func (s *statsService) Aggregate(stats []domain.UsageStats, groupBy string) []map[string]interface{} {
	switch groupBy {
	case "provider":
		return s.aggregateByProvider(stats)
	case "model":
		return s.aggregateByModel(stats)
	case "date":
		return s.aggregateByDate(stats)
	default:
		return s.aggregateByProvider(stats)
	}
}

func (s *statsService) aggregateByProvider(stats []domain.UsageStats) []map[string]interface{} {
	aggregated := make(map[string]int)
	for _, stat := range stats {
		aggregated[stat.ProviderID] += stat.RequestCount
	}
	result := make([]map[string]interface{}, 0, len(aggregated))
	for providerID, count := range aggregated {
		result = append(result, map[string]interface{}{
			"provider_id":   providerID,
			"request_count": count,
		})
	}
	return result
}

func (s *statsService) aggregateByModel(stats []domain.UsageStats) []map[string]interface{} {
	aggregated := make(map[string]int)
	for _, stat := range stats {
		key := stat.ProviderID + "/" + stat.ModelName
		aggregated[key] += stat.RequestCount
	}
	result := make([]map[string]interface{}, 0, len(aggregated))
	for key, count := range aggregated {
		parts := strings.SplitN(key, "/", 2)
		result = append(result, map[string]interface{}{
			"provider_id":   parts[0],
			"model_name":    parts[1],
			"request_count": count,
		})
	}
	return result
}

func (s *statsService) aggregateByDate(stats []domain.UsageStats) []map[string]interface{} {
	aggregated := make(map[string]int)
	for _, stat := range stats {
		key := stat.Date.Format("2006-01-02")
		aggregated[key] += stat.RequestCount
	}
	result := make([]map[string]interface{}, 0, len(aggregated))
	for date, count := range aggregated {
		result = append(result, map[string]interface{}{
			"date":          date,
			"request_count": count,
		})
	}
	return result
}
