package service

import (
	"fmt"

	"golang.org/x/sync/errgroup"
)

// TrendResult 趋势返回结构
type TrendResult struct {
	Energy    []TrendPoint `json:"energy"`
	Comments  []TrendPoint `json:"comments"`
	Likes     []TrendPoint `json:"likes"`
	Favorites []TrendPoint `json:"favorites"`
	Views     []TrendPoint `json:"views"`
}

// TrendsService Studio 趋势分析服务
type TrendsService struct {
	energyRepo   EnergyTrendStore
	commentRepo  CommentTrendStore
	likeRepo     LikeTrendStore
	favoriteRepo FavoriteTrendStore
	viewRepo     ViewTrendStore
}

// NewTrendsService 构造函数
func NewTrendsService(energyRepo EnergyTrendStore, commentRepo CommentTrendStore, likeRepo LikeTrendStore, favoriteRepo FavoriteTrendStore, viewRepo ViewTrendStore) *TrendsService {
	return &TrendsService{
		energyRepo:   energyRepo,
		commentRepo:  commentRepo,
		likeRepo:     likeRepo,
		favoriteRepo: favoriteRepo,
		viewRepo:     viewRepo,
	}
}

// GetTrends 获取指定时间范围的趋势数据（并行查询四项趋势）
func (s *TrendsService) GetTrends(userID uint, since string) (*TrendResult, error) {
	result := &TrendResult{}
	g := new(errgroup.Group)

	g.Go(func() error {
		var err error
		result.Energy, err = s.energyRepo.AggregateEnergyByAuthor(userID, since)
		if err != nil {
			return fmt.Errorf("查询赋能趋势: %w", err)
		}
		return nil
	})

	g.Go(func() error {
		var err error
		result.Comments, err = s.commentRepo.AggregateCommentsByAuthor(userID, since)
		if err != nil {
			return fmt.Errorf("查询评论趋势: %w", err)
		}
		return nil
	})

	g.Go(func() error {
		var err error
		result.Likes, err = s.likeRepo.AggregateLikesByAuthor(userID, since)
		if err != nil {
			return fmt.Errorf("查询点赞趋势: %w", err)
		}
		return nil
	})

	g.Go(func() error {
		var err error
		result.Favorites, err = s.favoriteRepo.AggregateFavoritesByAuthor(userID, since)
		if err != nil {
			return fmt.Errorf("查询收藏趋势: %w", err)
		}
		return nil
	})

	g.Go(func() error {
		var err error
		result.Views, err = s.viewRepo.AggregateViewsByAuthor(userID, since)
		if err != nil {
			return fmt.Errorf("查询阅读趋势: %w", err)
		}
		return nil
	})

	if err := g.Wait(); err != nil {
		return nil, err
	}

	return result, nil
}
