//go:build integration

package inttest

import (
	"context"
	"testing"

	"github.com/google/uuid"

	"scrabble/backend/internal/payments"
)

// TestPaymentAvailabilityKillSwitch exercises the per-rail kill switch + the per-account override
// end-to-end against Postgres: fail-open, a disabled rail with a localized message, per-rail
// granularity, and the allow/deny/default overrides.
func TestPaymentAvailabilityKillSwitch(t *testing.T) {
	ctx := context.Background()
	svc := newPaymentsService()
	acc := uuid.New()

	// Fail-open: an untouched rail is enabled.
	if ok, _, err := svc.CanPurchase(ctx, acc, payments.RailDirectWeb, "en"); err != nil || !ok {
		t.Fatalf("fail-open: CanPurchase = %v/%v, want true", ok, err)
	}

	// Disable the web rail with a per-language message → blocked with that message, localized.
	if err := svc.SetRailStatus(ctx, payments.RailDirectWeb, payments.RailAvailability{MessageRU: "Чиним", MessageEN: "Fixing"}); err != nil {
		t.Fatalf("set rail status: %v", err)
	}
	if ok, reason, err := svc.CanPurchase(ctx, acc, payments.RailDirectWeb, "ru"); err != nil || ok || reason != "Чиним" {
		t.Fatalf("disabled rail (ru): CanPurchase = %v/%q/%v, want false/Чиним", ok, reason, err)
	}
	if ok, reason, _ := svc.CanPurchase(ctx, acc, payments.RailDirectWeb, "en"); ok || reason != "Fixing" {
		t.Fatalf("disabled rail (en): = %v/%q, want false/Fixing", ok, reason)
	}
	// Per-rail granularity: another rail stays enabled.
	if ok, _, _ := svc.CanPurchase(ctx, acc, payments.RailDirectAndroid, "en"); !ok {
		t.Fatalf("android rail should stay enabled")
	}

	// A per-account "allow" override bypasses the disabled rail.
	if err := svc.SetPurchaseOverride(ctx, acc, payments.OverrideAllow); err != nil {
		t.Fatalf("set override allow: %v", err)
	}
	if ok, _, _ := svc.CanPurchase(ctx, acc, payments.RailDirectWeb, "en"); !ok {
		t.Fatalf("allow override should bypass the disabled rail")
	}
	if ov, err := svc.PurchaseOverrideFor(ctx, acc); err != nil || ov != payments.OverrideAllow {
		t.Fatalf("PurchaseOverrideFor = %v/%v, want allow", ov, err)
	}

	// A "deny" override blocks even an enabled rail.
	if err := svc.SetPurchaseOverride(ctx, acc, payments.OverrideDeny); err != nil {
		t.Fatalf("set override deny: %v", err)
	}
	if ok, reason, _ := svc.CanPurchase(ctx, acc, payments.RailDirectAndroid, "en"); ok || reason == "" {
		t.Fatalf("deny override should block the enabled android rail with a reason, got %v/%q", ok, reason)
	}

	// Clearing the override (default) restores rail-driven behaviour.
	if err := svc.SetPurchaseOverride(ctx, acc, payments.OverrideDefault); err != nil {
		t.Fatalf("clear override: %v", err)
	}
	if ov, _ := svc.PurchaseOverrideFor(ctx, acc); ov != payments.OverrideDefault {
		t.Fatalf("after clear, override = %v, want default", ov)
	}
	if ok, _, _ := svc.CanPurchase(ctx, acc, payments.RailDirectAndroid, "en"); !ok {
		t.Fatalf("after clearing override, android rail should be enabled again")
	}

	// RailStatuses reflects the stored web-rail change and fills the rest fail-open.
	all, err := svc.RailStatuses(ctx)
	if err != nil {
		t.Fatalf("rail statuses: %v", err)
	}
	if all[payments.RailDirectWeb].Enabled {
		t.Fatalf("web rail should read disabled")
	}
	if !all[payments.RailVK].Enabled {
		t.Fatalf("untouched vk rail should read enabled")
	}
}
