package factcheck

import (
	"context"
	"encoding/json"
	"os"
	"testing"

	"aigateway.local/core/internal/platform/config"
	"aigateway.local/core/internal/platform/database"
)

func TestFactCheckPostgreSQLLifecycle(t *testing.T) {
	databaseURL := os.Getenv("FACTCHECK_TEST_DATABASE_URL")
	if databaseURL == "" {
		t.Skip("FACTCHECK_TEST_DATABASE_URL is not set")
	}
	ctx := context.Background()
	pool, err := database.Open(ctx, config.Database{URL: databaseURL, MaxConns: 4})
	if err != nil {
		t.Fatal(err)
	}
	defer pool.Close()

	const actorID = "33333333-3333-4333-8333-333333333333"
	const knowledgeBaseID = "44444444-4444-4444-8444-444444444444"
	const eventID = "55555555-5555-4555-8555-555555555555"
	_, err = pool.Exec(ctx, `INSERT INTO gateway.admin_accounts(id,username,password_hash,role)
		VALUES($1,'factcheck-test-admin','test','superadmin') ON CONFLICT(id) DO NOTHING`, actorID)
	if err != nil {
		t.Fatal(err)
	}
	cleanup := func() {
		_, _ = pool.Exec(ctx, `DELETE FROM gateway.fact_check_events WHERE id=$1`, eventID)
		_, _ = pool.Exec(ctx, `DELETE FROM gateway.fact_check_policies WHERE scope='global'`)
		_, _ = pool.Exec(ctx, `DELETE FROM gateway.knowledge_bases WHERE id=$1`, knowledgeBaseID)
		_, _ = pool.Exec(ctx, `UPDATE gateway.fact_check_settings SET provider_id=NULL,model='',updated_by=NULL`)
		_, _ = pool.Exec(ctx, `DELETE FROM gateway.admin_accounts WHERE id=$1`, actorID)
	}
	cleanup()
	_, err = pool.Exec(ctx, `INSERT INTO gateway.admin_accounts(id,username,password_hash,role)
		VALUES($1,'factcheck-test-admin','test','superadmin') ON CONFLICT(id) DO NOTHING`, actorID)
	if err != nil {
		t.Fatal(err)
	}
	defer cleanup()
	_, err = pool.Exec(ctx, `INSERT INTO gateway.knowledge_bases(id,name,retrieval_mode,chunk_size,chunk_overlap,created_by)
		VALUES($1,'factcheck-test-kb','postgres_fts',800,100,$2)`, knowledgeBaseID, actorID)
	if err != nil {
		t.Fatal(err)
	}

	service := NewService(pool)
	settings, err := service.SaveSettings(ctx, Settings{TimeoutSeconds: 17}, actorID)
	if err != nil || settings.TimeoutSeconds != 17 || settings.ProviderID != nil {
		t.Fatalf("settings=%#v err=%v", settings, err)
	}
	policy, err := service.SavePolicy(ctx, Policy{
		Scope:            "global",
		Enabled:          true,
		Mode:             "sync",
		Action:           "annotate",
		KnowledgeBaseIDs: []string{knowledgeBaseID},
	}, actorID)
	if err != nil {
		t.Fatal(err)
	}
	if policy.Revision != 1 || policy.TopK != 4 || policy.SupportThreshold != 70 {
		t.Fatalf("unexpected policy defaults: %#v", policy)
	}
	policy.Action = "block"
	updated, err := service.SavePolicy(ctx, policy, actorID)
	if err != nil || updated.Revision != 2 || updated.Action != "block" {
		t.Fatalf("updated=%#v err=%v", updated, err)
	}

	claims := json.RawMessage(`[{"text":"Go gateway"}]`)
	evidence := json.RawMessage(`[{"source":"kb"}]`)
	_, err = pool.Exec(ctx, `INSERT INTO gateway.fact_check_events
		(id,policy_id,request_id,model,mode,action,verdict,support_score,latency_ms,question,answer,claims,evidence)
		VALUES($1,$2,'factcheck-request','test-model','sync','block','supported',92,12,'question','answer',$3,$4)`,
		eventID, policy.ID, claims, evidence)
	if err != nil {
		t.Fatal(err)
	}
	events, err := service.Events(ctx, "supported", 10)
	if err != nil || len(events) != 1 {
		t.Fatalf("events=%#v err=%v", events, err)
	}
	if events[0].Question != "" || events[0].Answer != "" || events[0].Claims != nil {
		t.Fatalf("event list leaked payload: %#v", events[0])
	}
	detail, err := service.Event(ctx, eventID)
	if err != nil || detail.Question != "question" || len(detail.Evidence) == 0 {
		t.Fatalf("detail=%#v err=%v", detail, err)
	}
	if err = service.DeletePolicy(ctx, policy.ID); err != nil {
		t.Fatal(err)
	}
}
