//go:build integration

package admin_test

import (
	"testing"

	"github.com/ultisuite/ulti-backend/internal/integrationtest"
)

func TestAdminOrgSettings(t *testing.T) {
	h := integrationtest.RequireHarness(t)
	adminClient, _ := integrationtest.RequireAdminClient(t, h)

	getResp, err := adminClient.Get("/api/v1/admin/org/settings")
	integrationtest.FailIf(err, t, "get org settings")
	integrationtest.FailUnlessStatus(t, getResp, 200)

	var initial map[string]any
	integrationtest.DecodeJSON(t, getResp, &initial)
	policy, ok := initial["policy"].(map[string]any)
	if !ok {
		t.Fatalf("missing policy: %#v", initial)
	}
	storage, ok := policy["storage_quotas"].(map[string]any)
	if !ok {
		t.Fatalf("missing storage_quotas: %#v", policy)
	}
	if storage["default_mail_gib"] == nil {
		t.Fatalf("expected default_mail_gib in policy")
	}

	putResp, err := adminClient.Put("/api/v1/admin/org/settings", map[string]any{
		"policy": map[string]any{
			"storage_quotas": map[string]any{
				"default_mail_gib": 10,
			},
			"usage_quotas": map[string]any{
				"llm_requests_per_day": 200,
			},
		},
	})
	integrationtest.FailIf(err, t, "put org settings")
	integrationtest.FailUnlessStatus(t, putResp, 200)

	var updated map[string]any
	integrationtest.DecodeJSON(t, putResp, &updated)
	updatedPolicy, ok := updated["policy"].(map[string]any)
	if !ok {
		t.Fatalf("missing policy after update: %#v", updated)
	}
	updatedStorage, ok := updatedPolicy["storage_quotas"].(map[string]any)
	if !ok {
		t.Fatalf("missing storage_quotas after update")
	}
	if updatedStorage["default_mail_gib"] != float64(10) {
		t.Fatalf("default_mail_gib = %v, want 10", updatedStorage["default_mail_gib"])
	}
}

func TestAdminOrgSettingsIdentityProvidersSecrets(t *testing.T) {
	h := integrationtest.RequireHarness(t)
	adminClient, _ := integrationtest.RequireAdminClient(t, h)

	providerID := "test-oauth-provider"
	putResp, err := adminClient.Put("/api/v1/admin/org/settings", map[string]any{
		"policy": map[string]any{
			"identity_providers": map[string]any{
				"allow_self_enrollment": true,
				"providers": []any{
					map[string]any{
						"id":      providerID,
						"name":    "Google Workspace",
						"slug":    "google-workspace",
						"type":    "oauth",
						"enabled": true,
						"oauth": map[string]any{
							"provider":      "google",
							"client_id":     "client-id",
							"client_secret": "super-secret",
							"scopes":        "openid email profile",
						},
						"allowed_email_domains": []any{"company.com"},
					},
				},
			},
		},
	})
	integrationtest.FailIf(err, t, "put identity providers")
	integrationtest.FailUnlessStatus(t, putResp, 200)

	var afterPut map[string]any
	integrationtest.DecodeJSON(t, putResp, &afterPut)
	secrets, ok := afterPut["secrets"].(map[string]any)
	if !ok {
		t.Fatalf("missing secrets: %#v", afterPut)
	}
	idpSecrets, ok := secrets["identity_providers"].(map[string]any)
	if !ok {
		t.Fatalf("missing identity provider secrets: %#v", secrets)
	}
	providerSecrets, ok := idpSecrets[providerID].(map[string]any)
	if !ok {
		t.Fatalf("missing provider secrets entry: %#v", idpSecrets)
	}
	oauthSecret, ok := providerSecrets["oauth_client_secret"].(map[string]any)
	if !ok || oauthSecret["configured"] != true {
		t.Fatalf("oauth secret not configured: %#v", providerSecrets)
	}

	policy, ok := afterPut["policy"].(map[string]any)
	if !ok {
		t.Fatalf("missing policy")
	}
	idpPolicy, ok := policy["identity_providers"].(map[string]any)
	if !ok {
		t.Fatalf("missing identity_providers policy")
	}
	providers, ok := idpPolicy["providers"].([]any)
	if !ok || len(providers) != 1 {
		t.Fatalf("expected one provider")
	}
	provider, ok := providers[0].(map[string]any)
	if !ok {
		t.Fatalf("invalid provider payload")
	}
	oauth, ok := provider["oauth"].(map[string]any)
	if !ok || oauth["client_secret"] != "" {
		t.Fatalf("client_secret should be masked on GET")
	}
}

func TestAdminOrgSettingsVirusTotalSecret(t *testing.T) {
	h := integrationtest.RequireHarness(t)
	adminClient, _ := integrationtest.RequireAdminClient(t, h)

	putResp, err := adminClient.Put("/api/v1/admin/org/settings", map[string]any{
		"policy": map[string]any{
			"file_policies": map[string]any{
				"virus_scan_enabled": true,
				"virustotal_api_key": "vt-test-secret-key",
			},
		},
	})
	integrationtest.FailIf(err, t, "put org settings with virustotal key")
	integrationtest.FailUnlessStatus(t, putResp, 200)

	var afterPut map[string]any
	integrationtest.DecodeJSON(t, putResp, &afterPut)
	secrets, ok := afterPut["secrets"].(map[string]any)
	if !ok {
		t.Fatalf("missing secrets: %#v", afterPut)
	}
	vtSecret, ok := secrets["virustotal_api_key"].(map[string]any)
	if !ok || vtSecret["configured"] != true {
		t.Fatalf("virustotal_api_key not configured: %#v", secrets)
	}
	filePolicies, ok := afterPut["policy"].(map[string]any)["file_policies"].(map[string]any)
	if !ok {
		t.Fatalf("missing file_policies")
	}
	if filePolicies["virustotal_api_key"] != "" {
		t.Fatalf("virustotal_api_key should be masked on GET, got %q", filePolicies["virustotal_api_key"])
	}

	// Empty patch must preserve stored secret.
	preserveResp, err := adminClient.Put("/api/v1/admin/org/settings", map[string]any{
		"policy": map[string]any{
			"file_policies": map[string]any{
				"virus_scan_enabled": false,
				"virustotal_api_key": "",
			},
		},
	})
	integrationtest.FailIf(err, t, "preserve virustotal key")
	integrationtest.FailUnlessStatus(t, preserveResp, 200)

	var preserved map[string]any
	integrationtest.DecodeJSON(t, preserveResp, &preserved)
	preservedSecrets, ok := preserved["secrets"].(map[string]any)
	if !ok {
		t.Fatalf("missing secrets after preserve")
	}
	vtPreserved, ok := preservedSecrets["virustotal_api_key"].(map[string]any)
	if !ok || vtPreserved["configured"] != true {
		t.Fatalf("virustotal key not preserved: %#v", preservedSecrets)
	}
}
