package service

import (
	"context"
	"errors"
	"testing"

	"oci-portal/internal/model"
	"oci-portal/internal/oci"
)

// importAliveConfig 导入一份测活成功、home region 为 FRA 的配置。
func importAliveConfig(t *testing.T, svc *OciConfigService) *model.OciConfig {
	t.Helper()
	cfg, err := svc.Import(context.Background(), trialImportInput())
	if err != nil {
		t.Fatalf("Import: %v", err)
	}
	return cfg
}

func TestRegionSubscriptionsEnrichesAlias(t *testing.T) {
	client := &fakeClient{
		tenancy: oci.TenancyInfo{Name: "t", HomeRegionKey: "FRA"},
		regionSubs: []oci.RegionSubscription{
			{Key: "FRA", Name: "eu-frankfurt-1", Status: "READY", IsHomeRegion: true},
			{Key: "XXX", Name: "not-in-local-table", Status: "READY"},
		},
	}
	svc := newTestService(t, client)
	cfg := importAliveConfig(t, svc)

	subs, err := svc.RegionSubscriptions(context.Background(), cfg.ID)
	if err != nil {
		t.Fatalf("RegionSubscriptions: %v", err)
	}
	if len(subs) != 2 {
		t.Fatalf("len(subs) = %d, want 2", len(subs))
	}
	if got, want := subs[0].Alias, "Germany Central (Frankfurt)"; got != want {
		t.Errorf("subs[0].Alias = %q, want %q", got, want)
	}
	if got, want := subs[1].Alias, ""; got != want {
		t.Errorf("subs[1].Alias = %q, want %q (本地表未收录时留空)", got, want)
	}
}

func TestSubscribeRegionUsesHomeRegion(t *testing.T) {
	client := &fakeClient{
		tenancy: oci.TenancyInfo{Name: "t", HomeRegionKey: "FRA"},
		regionSubs: []oci.RegionSubscription{
			{Key: "FRA", Name: "eu-frankfurt-1", Status: "READY", IsHomeRegion: true},
			{Key: "AMS", Name: "eu-amsterdam-1", Status: "IN_PROGRESS"},
		},
	}
	svc := newTestService(t, client)
	cfg := importAliveConfig(t, svc)

	subs, err := svc.SubscribeRegion(context.Background(), cfg.ID, " ams ")
	if err != nil {
		t.Fatalf("SubscribeRegion: %v", err)
	}
	if got, want := client.subscribedKey, "AMS"; got != want {
		t.Errorf("subscribed key = %q, want %q (应去空格并大写)", got, want)
	}
	if got, want := client.subscribedHomeRegion, "eu-frankfurt-1"; got != want {
		t.Errorf("home region = %q, want %q (应由 HomeRegionKey 映射)", got, want)
	}
	if len(subs) != 2 {
		t.Errorf("len(subs) = %d, want 2 (订阅后返回最新列表)", len(subs))
	}
}

func TestSubscribeRegionRejectsEmptyKey(t *testing.T) {
	svc := newTestService(t, &fakeClient{tenancy: oci.TenancyInfo{Name: "t"}})
	cfg := importAliveConfig(t, svc)
	if _, err := svc.SubscribeRegion(context.Background(), cfg.ID, "  "); err == nil {
		t.Error("SubscribeRegion(empty): got nil error, want failure")
	}
}

func TestSubscribeRegionPropagatesError(t *testing.T) {
	client := &fakeClient{
		tenancy:      oci.TenancyInfo{Name: "t", HomeRegionKey: "FRA"},
		subscribeErr: errors.New("NotAuthorizedOrNotFound"),
	}
	svc := newTestService(t, client)
	cfg := importAliveConfig(t, svc)
	if _, err := svc.SubscribeRegion(context.Background(), cfg.ID, "AMS"); err == nil {
		t.Error("SubscribeRegion with cloud error: got nil error, want failure")
	}
}

func TestLimitsPassesQuery(t *testing.T) {
	client := &fakeClient{
		tenancy: oci.TenancyInfo{Name: "t", HomeRegionKey: "FRA"},
		limitValues: []oci.LimitValue{
			{Name: "standard-a1-core-count", ScopeType: "AD", AvailabilityDomain: "AD-1", Value: 6},
		},
	}
	svc := newTestService(t, client)
	cfg := importAliveConfig(t, svc)

	q := oci.LimitsQuery{Region: "eu-frankfurt-1", Service: "compute", Name: "standard-a1-core-count", WithAvailability: true}
	values, err := svc.Limits(context.Background(), cfg.ID, q)
	if err != nil {
		t.Fatalf("Limits: %v", err)
	}
	if len(values) != 1 {
		t.Fatalf("len(values) = %d, want 1", len(values))
	}
	if got, want := client.limitsQuery, q; got != want {
		t.Errorf("query passed to client = %+v, want %+v", got, want)
	}
}

func TestLimitsRequiresService(t *testing.T) {
	svc := newTestService(t, &fakeClient{tenancy: oci.TenancyInfo{Name: "t"}})
	cfg := importAliveConfig(t, svc)
	if _, err := svc.Limits(context.Background(), cfg.ID, oci.LimitsQuery{}); err == nil {
		t.Error("Limits without service: got nil error, want failure")
	}
}
