package services

// Live-DB test for the submission-draft auto-naming scheme
// (t-paliad-352 / m/paliad#155). Skipped without TEST_DATABASE_URL.
//
// Verifies the shipped Create flow end-to-end against real Postgres:
// a project-bound draft is auto-named "<date> <client> ./. <forum> ./.
// <opponent>" rather than "Entwurf N", the segments resolve from the
// real project tree (client = root ancestor, forum = proceeding-type
// jurisdiction, opponent = opposing party by our_side), and a second
// draft on the same slot de-duplicates with a " (2)" suffix.

import (
	"context"
	"os"
	"testing"
	"time"

	"github.com/google/uuid"
	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"

	"mgit.msbls.de/m/paliad/internal/db"
)

func TestSubmissionDraft_AutoName_Live(t *testing.T) {
	url := os.Getenv("TEST_DATABASE_URL")
	if url == "" {
		t.Skip("TEST_DATABASE_URL not set — skipping live DB test")
	}
	if err := db.ApplyMigrations(url); err != nil {
		t.Fatalf("apply migrations: %v", err)
	}
	pool, err := sqlx.Connect("postgres", url)
	if err != nil {
		t.Fatalf("connect: %v", err)
	}
	defer pool.Close()
	ctx := context.Background()

	userID := uuid.New()
	email := "autoname-" + userID.String()[:8] + "@hlc.com"
	var clientID, caseID uuid.UUID
	cleanup := func() {
		pool.ExecContext(ctx, `DELETE FROM paliad.submission_drafts WHERE user_id = $1`, userID)
		pool.ExecContext(ctx, `DELETE FROM paliad.parties WHERE project_id = $1`, caseID)
		// Children first (FK), then root.
		pool.ExecContext(ctx, `DELETE FROM paliad.project_teams WHERE user_id = $1`, userID)
		pool.ExecContext(ctx, `DELETE FROM paliad.projects WHERE id = $1`, caseID)
		pool.ExecContext(ctx, `DELETE FROM paliad.projects WHERE id = $1`, clientID)
		pool.ExecContext(ctx, `DELETE FROM paliad.users WHERE id = $1`, userID)
		pool.ExecContext(ctx, `DELETE FROM auth.users WHERE id = $1`, userID)
	}
	defer cleanup()
	if _, err := pool.ExecContext(ctx, `INSERT INTO auth.users (id, email) VALUES ($1, $2)`, userID, email); err != nil {
		t.Fatalf("seed auth.users: %v", err)
	}
	if _, err := pool.ExecContext(ctx,
		`INSERT INTO paliad.users (id, email, display_name, office, global_role, lang)
		 VALUES ($1, $2, 'Auto Name', 'munich', 'standard', 'de')`, userID, email); err != nil {
		t.Fatalf("seed paliad.users: %v", err)
	}

	users := NewUserService(pool)
	projects := NewProjectService(pool, users)
	parties := NewPartyService(pool, projects)
	vars := NewSubmissionVarsService(pool, projects, parties, users)
	renderer := NewSubmissionRenderer()
	drafts := NewSubmissionDraftService(pool, projects, vars, renderer)

	// Client root → case child. The case carries the proceeding type
	// (UPC) and our_side (claimant), the party is the opponent.
	client, err := projects.Create(ctx, userID, CreateProjectInput{
		Type: "client", Title: "Bayer AG",
	})
	if err != nil {
		t.Fatalf("create client project: %v", err)
	}
	clientID = client.ID

	ptID := 8 // upc.inf.cfi → jurisdiction UPC
	side := "claimant"
	caseProj, err := projects.Create(ctx, userID, CreateProjectInput{
		Type: "case", Title: "Streitsache", ParentID: &client.ID,
		ProceedingTypeID: &ptID, OurSide: &side,
	})
	if err != nil {
		t.Fatalf("create case project: %v", err)
	}
	caseID = caseProj.ID

	beklagte := "Beklagte"
	if _, err := parties.Create(ctx, userID, caseProj.ID, CreatePartyInput{
		Name: "Novartis Pharma", Role: &beklagte,
	}); err != nil {
		t.Fatalf("create party: %v", err)
	}

	loc, _ := time.LoadLocation("Europe/Berlin")
	today := time.Now().In(loc).Format("2006-01-02")
	wantBase := today + " Bayer AG ./. UPC ./. Novartis Pharma"

	d1, err := drafts.Create(ctx, userID, &caseProj.ID, "upc.inf.cfi.sod", "de")
	if err != nil {
		t.Fatalf("create draft 1: %v", err)
	}
	if d1.Name != wantBase {
		t.Fatalf("draft 1 name = %q, want %q", d1.Name, wantBase)
	}

	// Second draft on the same (project, code) slot must de-duplicate.
	d2, err := drafts.Create(ctx, userID, &caseProj.ID, "upc.inf.cfi.sod", "de")
	if err != nil {
		t.Fatalf("create draft 2: %v", err)
	}
	want2 := wantBase + " (2)"
	if d2.Name != want2 {
		t.Fatalf("draft 2 name = %q, want %q", d2.Name, want2)
	}

	// A project-less draft keeps the legacy Entwurf-N counter.
	dless, err := drafts.Create(ctx, userID, nil, "upc.inf.cfi.sod", "de")
	if err != nil {
		t.Fatalf("create project-less draft: %v", err)
	}
	if dless.Name != "Entwurf 1" {
		t.Fatalf("project-less draft name = %q, want %q", dless.Name, "Entwurf 1")
	}
}
