package com.bytelyst.platform

import kotlinx.coroutines.test.runTest
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class BLLicenseClientTest {

    private lateinit var server: MockWebServer
    private lateinit var config: BLPlatformConfig

    @BeforeEach
    fun setup() {
        server = MockWebServer()
        server.start()
        config = BLPlatformConfig(
            productId = "testapp",
            baseUrl = server.url("/api").toString().trimEnd('/'),
            applicationId = "com.test.app",
        )
    }

    @AfterEach
    fun teardown() {
        server.shutdown()
    }

    @Test
    fun `activate returns success result`() = runTest {
        server.enqueue(
            MockResponse()
                .setBody("""{"success":true,"plan":"pro","message":"Activated"}""")
                .setResponseCode(200)
        )

        val client = BLLicenseClient(config)
        val result = client.activate("LYSNR-ABCD-1234")

        assertTrue(result.success)
        assertEquals("pro", result.plan)
        assertEquals("Activated", result.message)
    }

    @Test
    fun `activate URL-encodes the license key`() = runTest {
        server.enqueue(
            MockResponse()
                .setBody("""{"success":true,"plan":"pro"}""")
                .setResponseCode(200)
        )

        val client = BLLicenseClient(config)
        client.activate("KEY+WITH SPACE")

        val recorded = server.takeRequest()
        assertTrue(recorded.path!!.contains("KEY%2BWITH+SPACE") || recorded.path!!.contains("KEY%2BWITH%20SPACE"))
    }

    @Test
    fun `activate sends productId in body`() = runTest {
        server.enqueue(
            MockResponse()
                .setBody("""{"success":true,"plan":"free"}""")
                .setResponseCode(200)
        )

        val client = BLLicenseClient(config)
        client.activate("TEST-KEY")

        val recorded = server.takeRequest()
        assertTrue(recorded.body.readUtf8().contains("testapp"))
    }

    @Test
    fun `activate returns failure on error`() = runTest {
        server.enqueue(MockResponse().setResponseCode(400).setBody("""{"error":"invalid"}"""))

        val client = BLLicenseClient(config)
        val result = client.activate("BAD-KEY")

        assertFalse(result.success)
        assertNotNull(result.message)
    }

    @Test
    fun `checkStatus returns valid license`() = runTest {
        server.enqueue(
            MockResponse()
                .setBody("""{"valid":true,"plan":"pro","expiresAt":"2027-01-01"}""")
                .setResponseCode(200)
        )

        val client = BLLicenseClient(config)
        val result = client.checkStatus("LYSNR-ABCD-1234")

        assertTrue(result.valid)
        assertEquals("pro", result.plan)
        assertEquals("2027-01-01", result.expiresAt)
    }

    @Test
    fun `checkStatus returns invalid on error`() = runTest {
        server.enqueue(MockResponse().setResponseCode(404).setBody("""{"error":"not found"}"""))

        val client = BLLicenseClient(config)
        val result = client.checkStatus("UNKNOWN")

        assertFalse(result.valid)
    }

    @Test
    fun `deactivate returns true on success`() = runTest {
        server.enqueue(MockResponse().setBody("{}").setResponseCode(200))

        val client = BLLicenseClient(config)
        val result = client.deactivate("LYSNR-ABCD-1234")

        assertTrue(result)
        val recorded = server.takeRequest()
        assertEquals("POST", recorded.method)
        assertTrue(recorded.path!!.contains("deactivate"))
    }

    @Test
    fun `deactivate returns false on error`() = runTest {
        server.enqueue(MockResponse().setResponseCode(500))

        val client = BLLicenseClient(config)
        val result = client.deactivate("LYSNR-ABCD-1234")

        assertFalse(result)
    }
}
