package queue

import (
	"context"
	"time"

	"gorm.io/gorm"

	caasmmodel "security-center-backend/internal/modules/caasm/model"
)

// Collector Metrics provides statistics about sync job performance
type CollectorMetrics struct {
	TotalCollections      int64            `json:"total_collections"`
	SuccessfulCollections int64            `json:"successful_collections"`
	FailedCollections     int64            `json:"failed_collections"`
	LastCollectionAt      *time.Time       `json:"last_collection_at,omitempty"`
	CollectionsByProvider map[string]int64 `json:"collections_by_provider,omitempty"`
	AvgDurationSeconds    float64          `json:"avg_duration_seconds,omitempty"`
}

// GetCollectorMetrics retrieves statistics from sync_jobs table
func GetCollectorMetrics(ctx context.Context, db *gorm.DB) (*CollectorMetrics, error) {
	metrics := &CollectorMetrics{
		CollectionsByProvider: make(map[string]int64),
	}

	// Count total collections in last 30 days
	query := db.WithContext(ctx).Model(&caasmmodel.SyncJob{}).
		Where("created_at >= ?", time.Now().Add(-30*24*time.Hour))

	if err := query.Count(&metrics.TotalCollections).Error; err != nil {
		return nil, err
	}

	// Count successful collections
	if err := query.Where("status = ?", caasmmodel.SyncJobSuccess).
		Count(&metrics.SuccessfulCollections).Error; err != nil {
		return nil, err
	}

	// Count failed collections
	if err := query.Where("status = ?", caasmmodel.SyncJobFailed).
		Count(&metrics.FailedCollections).Error; err != nil {
		return nil, err
	}

	// Get last collection time
	var lastJob caasmmodel.SyncJob
	if err := db.WithContext(ctx).Model(&caasmmodel.SyncJob{}).
		Order("created_at desc").
		Limit(1).
		Select("created_at").
		First(&lastJob).Error; err == nil {
		metrics.LastCollectionAt = &lastJob.CreatedAt
	}

	// Get collections by provider (requires join with cloud_accounts)
	type ProviderCount struct {
		Provider string
		Count    int64
	}
	var providerCounts []ProviderCount

	err := db.WithContext(ctx).
		Table("sync_jobs").
		Select("ca.provider, COUNT(*) as count").
		Joins("LEFT JOIN cloud_accounts ca ON sync_jobs.cloud_account_id = ca.id").
		Where("sync_jobs.created_at >= ?", time.Now().Add(-30*24*time.Hour)).
		Group("ca.provider").
		Scan(&providerCounts).Error

	if err == nil {
		for _, pc := range providerCounts {
			if pc.Provider != "" {
				metrics.CollectionsByProvider[pc.Provider] = pc.Count
			}
		}
	}

	// Calculate average duration (in seconds)
	type AvgDuration struct {
		AvgSeconds float64
	}
	var avgDur AvgDuration

	err = db.WithContext(ctx).
		Table("sync_jobs").
		Select("AVG(TIMESTAMPDIFF(SECOND, started_at, finished_at)) as avg_seconds").
		Where("started_at IS NOT NULL").
		Where("finished_at IS NOT NULL").
		Where("created_at >= ?", time.Now().Add(-30*24*time.Hour)).
		Scan(&avgDur).Error

	if err == nil {
		metrics.AvgDurationSeconds = avgDur.AvgSeconds
	}

	return metrics, nil
}
