import XCTest

/// Phase 3 — Cleanup tests run sequentially after all parallel suites.
/// Clears test data via the admin API, then re-seeds the required accounts.
final class SuiteZZ_CleanupTests: XCTestCase {

    override func setUp() {
        super.setUp()
        continueAfterFailure = true
    }

    // MARK: - Clear All Data

    func testCleanup01_clearAllTestData() {
        let baseURL = TestAccountAPIClient.baseURL

        // 1. Login to admin panel (admin API uses Bearer token)
        // Try re-seeded password first, then fallback to default
        var adminToken = adminLogin(baseURL: baseURL, password: "test1234")
        if adminToken == nil {
            adminToken = adminLogin(baseURL: baseURL, password: "password123")
        }
        XCTAssertNotNil(adminToken, "Admin login failed — cannot clear test data")
        guard let token = adminToken else { return }

        // 2. Call clear-all-data
        let clearResult = adminClearAllData(baseURL: baseURL, token: token)
        XCTAssertTrue(clearResult, "Failed to clear all test data via admin API")
    }

    // MARK: - Re-Seed Accounts

    func testCleanup02_reSeedTestUser() {
        let session = TestAccountAPIClient.createVerifiedAccount(
            username: "testuser",
            email: "testuser@honeydue.com",
            password: "TestPass123!"
        )
        XCTAssertNotNil(session, "Failed to re-seed testuser account after cleanup")
    }

    func testCleanup03_reSeedAdmin() {
        let session = TestAccountAPIClient.createVerifiedAccount(
            username: "admin",
            email: "admin@honeydue.com",
            password: "Test1234"
        )
        XCTAssertNotNil(session, "Failed to re-seed admin account after cleanup")
    }

    // MARK: - Private Helpers

    /// Admin API uses `Bearer` token (not `Token` prefix), so we use inline URLRequest.
    private func adminLogin(baseURL: String, password: String = "test1234") -> String? {
        guard let url = URL(string: "\(baseURL)/admin/auth/login") else { return nil }

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.timeoutInterval = 15

        let body: [String: Any] = [
            "email": "admin@honeydue.com",
            "password": password
        ]
        request.httpBody = try? JSONSerialization.data(withJSONObject: body)

        let semaphore = DispatchSemaphore(value: 0)
        var token: String?

        URLSession.shared.dataTask(with: request) { data, response, _ in
            defer { semaphore.signal() }
            guard let data = data,
                  let status = (response as? HTTPURLResponse)?.statusCode,
                  (200...299).contains(status),
                  let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
                  let t = json["token"] as? String else { return }
            token = t
        }.resume()
        semaphore.wait()

        return token
    }

    private func adminClearAllData(baseURL: String, token: String) -> Bool {
        guard let url = URL(string: "\(baseURL)/admin/settings/clear-all-data") else { return false }

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
        request.timeoutInterval = 30

        let semaphore = DispatchSemaphore(value: 0)
        var success = false

        URLSession.shared.dataTask(with: request) { _, response, _ in
            defer { semaphore.signal() }
            if let status = (response as? HTTPURLResponse)?.statusCode {
                success = (200...299).contains(status)
            }
        }.resume()
        semaphore.wait()

        return success
    }
}
