package files

import (
	"context"
	"regexp"
	"testing"
	"time"

	"github.com/DATA-DOG/go-sqlmock"
)

func TestCleanupExpiredUploadOperations(t *testing.T) {
	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherRegexp))
	if err != nil {
		t.Fatalf("sqlmock.New: %v", err)
	}
	defer db.Close()

	now := time.Date(2026, 4, 17, 11, 30, 0, 0, time.UTC)
	mock.ExpectExec(regexp.QuoteMeta("DELETE FROM `_System_FileUploadOperation` WHERE `ExpiresAt` IS NOT NULL AND `ExpiresAt` < ?")).
		WithArgs(now).
		WillReturnResult(sqlmock.NewResult(0, 7))

	deleted, err := CleanupExpiredUploadOperations(context.Background(), db, now)
	if err != nil {
		t.Fatalf("CleanupExpiredUploadOperations: %v", err)
	}
	if deleted != 7 {
		t.Fatalf("deleted = %d, want 7", deleted)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("expectations: %v", err)
	}
}

func TestQueryUploadOperationMetrics(t *testing.T) {
	db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherRegexp))
	if err != nil {
		t.Fatalf("sqlmock.New: %v", err)
	}
	defer db.Close()

	now := time.Date(2026, 4, 17, 11, 30, 0, 0, time.UTC)

	mock.ExpectQuery(regexp.QuoteMeta("SELECT COUNT(*) FROM `_System_FileUploadOperation`")).
		WillReturnRows(sqlmock.NewRows([]string{"COUNT(*)"}).AddRow(9))
	mock.ExpectQuery(regexp.QuoteMeta("SELECT `State`, COUNT(*) FROM `_System_FileUploadOperation` GROUP BY `State`")).
		WillReturnRows(sqlmock.NewRows([]string{"State", "COUNT(*)"}).
			AddRow(uploadStatePrepared, 2).
			AddRow(uploadStateBlobStored, 1).
			AddRow(uploadStateCompleted, 4).
			AddRow(uploadStateFailed, 2))
	mock.ExpectQuery(regexp.QuoteMeta("SELECT COUNT(*) FROM `_System_FileUploadOperation` WHERE `ExpiresAt` IS NOT NULL AND `ExpiresAt` < ?")).
		WithArgs(now).
		WillReturnRows(sqlmock.NewRows([]string{"COUNT(*)"}).AddRow(3))

	metrics, err := QueryUploadOperationMetrics(context.Background(), db, now)
	if err != nil {
		t.Fatalf("QueryUploadOperationMetrics: %v", err)
	}
	if metrics.Total != 9 || metrics.Prepared != 2 || metrics.BlobStored != 1 || metrics.Completed != 4 || metrics.Failed != 2 || metrics.Expired != 3 {
		t.Fatalf("metrics = %+v", metrics)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("expectations: %v", err)
	}
}

func TestQueryUploadOperationMetrics_NilDB(t *testing.T) {
	metrics, err := QueryUploadOperationMetrics(context.Background(), nil, time.Now())
	if err != nil {
		t.Fatalf("QueryUploadOperationMetrics(nil): %v", err)
	}
	if metrics != (UploadOperationMetrics{}) {
		t.Fatalf("metrics = %+v, want zero value", metrics)
	}
}
