package installation

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

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/coredb"
	"github.com/tidbcloud/AgentTeam/internal/coredb/testkit"
)

var installationServiceTiDB testkit.TiDBCoreDBFixture

func TestMain(m *testing.M) {
	os.Exit(testkit.RunTestsWithTiDBCoreDBFixture(m, "appinstallation", &installationServiceTiDB))
}

func startDB(t *testing.T, ctx context.Context) coredb.DB {
	t.Helper()
	return installationServiceTiDB.RollbackDB(t, ctx)
}

type memberFixture struct {
	UserID      string
	MemberID    string
	WorkspaceID string
}

func mustExec(t *testing.T, execer coredb.QueryExecer, query string, args ...any) {
	t.Helper()
	_, err := execer.Exec(context.Background(), query, args...)
	require.NoError(t, err)
}

// seedWorkspace creates a workspace with one admin and optional extra members.
func seedWorkspace(t *testing.T, db coredb.QueryExecer, suffix string, now time.Time) (admin memberFixture, members []memberFixture) {
	t.Helper()
	admin = memberFixture{
		UserID:      "usr_" + suffix + "_admin",
		WorkspaceID: "wsp_" + suffix,
		MemberID:    "mem_" + suffix + "_admin",
	}
	mustExec(t, db, `
INSERT INTO users (id, email, name, display_name, password_hash, is_admin, email_verified_at, created_at, updated_at)
VALUES ($1, $2, $3, $3, 'hash', FALSE, $4, $4, $4)
`, admin.UserID, suffix+"-admin@example.com", suffix, now)
	mustExec(t, db, `
INSERT INTO organizations (id, name, slug, created_by_user_id, created_at, updated_at)
VALUES ($1, $2, $2, $3, $4, $4)
`, "org_"+suffix, suffix, admin.UserID, now)
	mustExec(t, db, `
INSERT INTO workspaces (id, organization_id, slug, name, latest_message_seq, created_at, updated_at)
VALUES ($1, $2, $3, $3, 0, $4, $4)
`, admin.WorkspaceID, "org_"+suffix, suffix, now)
	mustExec(t, db, `
INSERT INTO members (id, workspace_id, type, display_name, user_id, workspace_role, status, created_at, updated_at)
VALUES ($1, $2, 'human', $3, $4, 'admin', 'active', $5, $5)
`, admin.MemberID, admin.WorkspaceID, suffix+"-admin", admin.UserID, now)
	return admin, members
}

func seedMember(t *testing.T, db coredb.QueryExecer, workspaceID string, suffix string, now time.Time) memberFixture {
	t.Helper()
	member := memberFixture{
		UserID:      "usr_" + suffix,
		MemberID:    "mem_" + suffix,
		WorkspaceID: workspaceID,
	}
	mustExec(t, db, `
INSERT INTO users (id, email, name, display_name, password_hash, is_admin, email_verified_at, created_at, updated_at)
VALUES ($1, $2, $3, $3, 'hash', FALSE, $4, $4, $4)
`, member.UserID, suffix+"@example.com", suffix, now)
	mustExec(t, db, `
INSERT INTO members (id, workspace_id, type, display_name, user_id, workspace_role, status, created_at, updated_at)
VALUES ($1, $2, 'human', $3, $4, 'member', 'active', $5, $5)
`, member.MemberID, workspaceID, suffix, member.UserID, now)
	return member
}
