import { APIRequestContext, request } from "@playwright/test"
import { ADMIN_TOKEN, API_BASE } from "../../fixtures/test-constants"

let adminContext: APIRequestContext | null = null

/**
 * Get or create a singleton admin API context with the ADMIN_TOKEN.
 */
async function getAdminContext(baseURL: string): Promise<APIRequestContext> {
    if (!adminContext) {
        adminContext = await request.newContext({
            baseURL,
            ignoreHTTPSErrors: true,
            extraHTTPHeaders: {
                Token: ADMIN_TOKEN,
            },
        })
    }
    return adminContext
}

/**
 * Delete a user by ID via admin API.
 */
export async function deleteUser(baseURL: string, userId: string): Promise<boolean> {
    const ctx = await getAdminContext(baseURL)
    const res = await ctx.delete(`${API_BASE}/user/${userId}`)
    return res.ok()
}

/**
 * Cleanup test users matching a pattern in their email.
 */
export async function cleanupTestUsers(baseURL: string, emailPattern: RegExp | string): Promise<number> {
    const ctx = await getAdminContext(baseURL)
    const res = await ctx.get(`${API_BASE}/user`)
    if (!res.ok()) return 0

    const users: { id?: string; _id?: string; email?: string }[] = await res.json()
    if (!Array.isArray(users)) return 0

    let deleted = 0
    for (const user of users) {
        const email = user.email || ""
        const matches = typeof emailPattern === "string" ? email.includes(emailPattern) : emailPattern.test(email)

        if (matches) {
            const userId = user.id || user._id
            if (userId) {
                const ok = await deleteUser(baseURL, userId)
                if (ok) deleted++
            }
        }
    }

    return deleted
}

/**
 * Cleanup all test data (users and tokens matching @test.example.com).
 */
export async function cleanupAllTestData(baseURL: string): Promise<{ users: number }> {
    const testPattern = "@test.example.com"
    const users = await cleanupTestUsers(baseURL, testPattern)
    return { users }
}

/**
 * Dispose the admin API context. Call in globalTeardown.
 */
export async function disposeAdminApi(): Promise<void> {
    if (adminContext) {
        await adminContext.dispose()
        adminContext = null
    }
}
