package mysql

import (
	"context"
	"fmt"
	"testing"
	"time"

	"gorm.io/driver/sqlite"
	"gorm.io/gorm"

	helicopterusage "wucher/internal/domain/helicopter_usage"
	"wucher/internal/shared/pkg/uuidv7"
)

func openHelicopterUsageTestDB(t *testing.T) *gorm.DB {
	t.Helper()
	dsn := fmt.Sprintf("file:helicopter_usage_test_%d?mode=memory&cache=shared", time.Now().UnixNano())
	db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{
		NowFunc:                                  func() time.Time { return time.Now().UTC() },
		DisableForeignKeyConstraintWhenMigrating: true,
	})
	if err != nil {
		t.Fatalf("open sqlite: %v", err)
	}
	if err := db.AutoMigrate(&helicopterusage.HelicopterUsage{}); err != nil {
		t.Fatalf("auto migrate: %v", err)
	}
	return db
}

// TestHelicopterUsageRepositoryDecimalRoundTrip guards that the formerly-int counters
// (landing, cycles, ccc, flight report, hook release, rotor brake) keep 2 decimals through
// a persist -> read cycle.
func TestHelicopterUsageRepositoryDecimalRoundTrip(t *testing.T) {
	db := openHelicopterUsageTestDB(t)
	repo := NewHelicopterUsageRepository(db)
	ctx := context.Background()

	helID := uuidv7.MustBytes()
	row := &helicopterusage.HelicopterUsage{HelicopterID: helID}
	row.ApplyManualSummary(helicopterusage.ManualSummaryInput{
		Landing:         usageF64(123.45),
		AirframeCycles:  usageF64(12.30),
		Engine1Ccc:      usageF64(44.25),
		FlightReport:    usageF64(80.10),
		HookRelease:     usageF64(10.75),
		RotorBrakeCycle: usageF64(8.99),
	})
	if err := repo.Create(ctx, row); err != nil {
		t.Fatalf("create: %v", err)
	}

	got, err := repo.GetByHelicopterID(ctx, helID)
	if err != nil {
		t.Fatalf("get: %v", err)
	}
	if got == nil {
		t.Fatalf("expected row")
	}
	cases := []struct {
		name string
		got  float64
		want float64
	}{
		{"total_landing", got.TotalLanding, 123.45},
		{"total_airframe_cycles", got.TotalAirframeCycles, 12.30},
		{"total_engine_1_ccc", got.TotalEngine1Ccc, 44.25},
		{"total_flight_report", got.TotalFlightReport, 80.10},
		{"total_hook_release", got.TotalHookRelease, 10.75},
		{"total_rotor_brake_cycle", got.TotalRotorBrakeCycle, 8.99},
		{"manual_landing", got.ManualLanding, 123.45},
	}
	for _, c := range cases {
		if c.got != c.want {
			t.Fatalf("%s = %v, want %v (decimal truncated?)", c.name, c.got, c.want)
		}
	}
}

func usageF64(v float64) *float64 { return &v }
