package repository

import (
	"time"

	"nex/backend/internal/config"
	"nex/backend/internal/domain"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

type statsRepository struct {
	db *gorm.DB
}

func NewStatsRepository(db *gorm.DB) StatsRepository {
	return &statsRepository{db: db}
}

func (r *statsRepository) Record(providerID, modelName string) error {
	now := time.Now()
	todayTime := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())

	stats := config.UsageStats{
		ProviderID:   providerID,
		ModelName:    modelName,
		RequestCount: 1,
		Date:         todayTime,
	}

	return r.db.Clauses(clause.OnConflict{
		Columns: []clause.Column{
			{Name: "provider_id"},
			{Name: "model_name"},
			{Name: "date"},
		},
		DoUpdates: clause.Assignments(map[string]interface{}{
			"request_count": gorm.Expr("request_count + 1"),
		}),
	}).Create(&stats).Error
}

func (r *statsRepository) BatchUpdate(providerID, modelName string, date time.Time, delta int) error {
	stats := config.UsageStats{
		ProviderID:   providerID,
		ModelName:    modelName,
		RequestCount: delta,
		Date:         date,
	}

	return r.db.Clauses(clause.OnConflict{
		Columns: []clause.Column{
			{Name: "provider_id"},
			{Name: "model_name"},
			{Name: "date"},
		},
		DoUpdates: clause.Assignments(map[string]interface{}{
			"request_count": gorm.Expr("request_count + ?", delta),
		}),
	}).Create(&stats).Error
}

func (r *statsRepository) Query(providerID, modelName string, startDate, endDate *time.Time) ([]domain.UsageStats, error) {
	var stats []config.UsageStats
	query := r.db.Model(&config.UsageStats{})

	if providerID != "" {
		query = query.Where("provider_id = ?", providerID)
	}
	if modelName != "" {
		query = query.Where("model_name = ?", modelName)
	}
	if startDate != nil {
		query = query.Where("date >= ?", startDate)
	}
	if endDate != nil {
		query = query.Where("date <= ?", endDate)
	}

	err := query.Order("date DESC").Find(&stats).Error
	if err != nil {
		return nil, err
	}

	result := make([]domain.UsageStats, len(stats))
	for i := range stats {
		result[i] = domain.UsageStats{
			ID:           stats[i].ID,
			ProviderID:   stats[i].ProviderID,
			ModelName:    stats[i].ModelName,
			RequestCount: stats[i].RequestCount,
			Date:         stats[i].Date,
		}
	}
	return result, nil
}
