package service

import (
	"context"
	"fmt"
	"log/slog"

	"github.com/TopherMayor/unified-media-manager/internal/db"
)

type DashboardStats struct {
	TotalMedia       int64            `json:"total_media"`
	Monitored        int64            `json:"monitored"`
	Unavailable      int64            `json:"unavailable"`
	Available        int64            `json:"available"`
	QualityUpgrades  int64            `json:"quality_upgrades"`
	QueuePending     int64            `json:"queue_pending"`
	QueueDownloading int64            `json:"queue_downloading"`
	QueueFailed      int64            `json:"queue_failed"`
	BlocklistCount   int64            `json:"blocklist_count"`
	BlocklistExpired int64            `json:"blocklist_expired"`
	IndexersEnabled  int64            `json:"indexers_enabled"`
	MediaByType      map[string]int64 `json:"media_by_type"`
	StorageByType    map[string]int64 `json:"storage_by_type"`
	RecentDownloads  int64            `json:"recent_downloads"`
}

type DashboardService struct {
	db *db.DB
}

func NewDashboardService(database *db.DB) *DashboardService {
	return &DashboardService{db: database}
}

func (s *DashboardService) Stats(ctx context.Context) (*DashboardStats, error) {
	stats := &DashboardStats{
		MediaByType:   make(map[string]int64),
		StorageByType: make(map[string]int64),
	}

	combinedQuery := `
	SELECT
		(SELECT COUNT(*) FROM media WHERE deleted_at IS NULL),
		(SELECT COUNT(*) FROM media WHERE monitored = true AND deleted_at IS NULL),
		(SELECT COUNT(*) FROM media WHERE status = 'unavailable' AND deleted_at IS NULL),
		(SELECT COUNT(*) FROM media WHERE status = 'available' AND deleted_at IS NULL),
		(SELECT COUNT(*) FROM media WHERE desired_quality IS NOT NULL AND current_quality IS NULL AND deleted_at IS NULL),
		(SELECT COUNT(*) FROM download_queue WHERE status = 'pending'),
		(SELECT COUNT(*) FROM download_queue WHERE status = 'downloading'),
		(SELECT COUNT(*) FROM download_queue WHERE status = 'failed'),
		(SELECT COUNT(*) FROM blocklist),
		(SELECT COUNT(*) FROM blocklist WHERE auto_expires_at IS NOT NULL AND auto_expires_at < NOW()),
		(SELECT COUNT(*) FROM indexers WHERE enabled = true),
		(SELECT COUNT(*) FROM download_history WHERE created_at > NOW() - INTERVAL '24 hours')`

	err := s.db.Pool.QueryRow(ctx, combinedQuery).Scan(
		&stats.TotalMedia, &stats.Monitored, &stats.Unavailable, &stats.Available,
		&stats.QualityUpgrades, &stats.QueuePending, &stats.QueueDownloading, &stats.QueueFailed,
		&stats.BlocklistCount, &stats.BlocklistExpired, &stats.IndexersEnabled, &stats.RecentDownloads)
	if err != nil {
		slog.Error("dashboard combined query failed", "error", err)
		return nil, fmt.Errorf("dashboard stats: %w", err)
	}

	rows, err := s.db.Pool.Query(ctx,
		"SELECT media_type, COUNT(*) FROM media WHERE deleted_at IS NULL GROUP BY media_type")
	if err == nil {
		defer rows.Close()
		for rows.Next() {
			var mediaType string
			var count int64
			if err := rows.Scan(&mediaType, &count); err == nil {
				stats.MediaByType[mediaType] = count
			}
		}
	}

	sRows, err := s.db.Pool.Query(ctx,
		`SELECT m.media_type, COALESCE(SUM(mf.file_size), 0)
		 FROM media m
		 JOIN media_files mf ON m.id = mf.media_id AND mf.deleted_at IS NULL
		 WHERE m.deleted_at IS NULL
		 GROUP BY m.media_type`)
	if err == nil {
		defer sRows.Close()
		for sRows.Next() {
			var mediaType string
			var totalSize int64
			if err := sRows.Scan(&mediaType, &totalSize); err == nil {
				stats.StorageByType[mediaType] = totalSize
			}
		}
	}

	return stats, nil
}
