package top.r394realms.ltdmanagertest.whitelist

import kotlinx.serialization.json.Json
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test
import top.r3944realms.ltdmanager.whitelist.data.WhitelistPlayerInfo
import top.r3944realms.ltdmanager.whitelist.response.WhitelistApiResponse

class WhitelistApiResponseTest {

    private val json = Json { ignoreUnknownKeys = true; coerceInputValues = true }

    // ====== WhitelistApiResponse ======

    @Test
    fun `deserialize list response with data`() {
        val response = json.decodeFromString<WhitelistApiResponse>(listResponseJson)
        assertEquals(200, response.code)
        assertEquals("查询成功", response.msg)
        assertEquals(42, response.count)
        assertEquals(2, response.data!!.size)
    }

    @Test
    fun `list response player info fields`() {
        val response = json.decodeFromString<WhitelistApiResponse>(listResponseJson)
        val player = response.data!![0]

        assertEquals(1, player.id)
        assertEquals("Steve", player.playerName)
        assertEquals("8667ba71b85a4004af54457a9734eed7", player.uuid)
        assertEquals("123456789", player.qq)
        assertEquals(1, player.status)
        assertEquals("北京市", player.regionFullName)
        assertEquals(85, player.totalScore)
        assertTrue(player.emailActive)
    }

    @Test
    fun `deserialize action response (approve)`() {
        val response = json.decodeFromString<WhitelistApiResponse>(approveResponseJson)
        assertEquals(200, response.code)
        assertEquals("已加入白名单", response.msg)
        assertNull(response.data)
        assertEquals(0, response.count)
    }

    @Test
    fun `deserialize action response (reject)`() {
        val response = json.decodeFromString<WhitelistApiResponse>(rejectResponseJson)
        assertEquals(200, response.code)
        assertEquals("已拒绝申请", response.msg)
    }

    @Test
    fun `deserialize action response (remove)`() {
        val response = json.decodeFromString<WhitelistApiResponse>(removeResponseJson)
        assertEquals(200, response.code)
        assertEquals("已从白名单移除", response.msg)
    }

    @Test
    fun `deserialize error response`() {
        val response = json.decodeFromString<WhitelistApiResponse>(errorResponseJson)
        assertEquals(500, response.code)
        assertEquals("操作失败，Rcon连接错误或玩家不存在", response.msg)
    }

    @Test
    fun `deserialize auth failure response`() {
        val response = json.decodeFromString<WhitelistApiResponse>(authFailJson)
        assertEquals(403, response.code)
        assertEquals("无权限：API Key 无效或未提供", response.msg)
    }

    // ====== WhitelistPlayerInfo with all fields ======

    @Test
    fun `deserialize full player info`() {
        val player = json.decodeFromString<WhitelistPlayerInfo>(fullPlayerJson)
        assertEquals(1, player.id)
        assertEquals("Steve", player.playerName)
        assertEquals("8667ba71b85a4004af54457a9734eed7", player.uuid)
        assertEquals("123456789", player.qq)
        assertEquals(1, player.status)
        assertEquals("我是建筑党", player.description)
        assertEquals("2026-06-01T12:00:00", player.createTime)
        assertEquals(110000L, player.regionCode)
        assertEquals("北京市", player.regionFullName)
        assertEquals(1, player.operatorId)
        assertEquals("admin", player.operatorUsername)
        assertEquals("管理员", player.operatorNickname)
        assertEquals(85, player.totalScore)
        assertTrue(player.emailActive)
    }

    @Test
    fun `deserialize player with null operator fields`() {
        val player = json.decodeFromString<WhitelistPlayerInfo>(playerWithNullOperatorJson)
        assertEquals(2, player.id)
        assertEquals("Alex", player.playerName)
        assertEquals("2222222", player.qq)
        assertEquals(2, player.status)
        assertNull(player.operatorId)
        assertNull(player.operatorUsername)
        assertNull(player.operatorNickname)
    }

    // ====== Empty/missing data ======

    @Test
    fun `deserialize list response with empty data array`() {
        val response = this.json.decodeFromString<WhitelistApiResponse>(
            """{"code":200,"msg":"查询成功","count":0,"data":[]}"""
        )
        assertEquals(0, response.count)
        assertTrue(response.data!!.isEmpty())
    }

    @Test
    fun `deserialize response with null data`() {
        val response = json.decodeFromString<WhitelistApiResponse>(approveResponseJson)
        assertNull(response.data)
    }

    // ====== Sample JSON payloads ======

    companion object {
        val listResponseJson = """
        {
          "code": 200,
          "msg": "查询成功",
          "count": 42,
          "data": [
            {
              "id": 1,
              "playerName": "Steve",
              "uuid": "8667ba71b85a4004af54457a9734eed7",
              "qq": "123456789",
              "status": 1,
              "description": "我是建筑党",
              "createTime": "2026-06-01T12:00:00",
              "regionCode": 110000,
              "regionFullName": "北京市",
              "operatorId": 1,
              "operatorUsername": "admin",
              "operatorNickname": "管理员",
              "totalScore": 85,
              "emailActive": true
            },
            {
              "id": 2,
              "playerName": "Alex",
              "uuid": "abc123",
              "qq": "987654321",
              "status": 1,
              "description": "",
              "createTime": "2026-06-02T08:00:00",
              "regionCode": 310000,
              "regionFullName": "上海市",
              "operatorId": null,
              "operatorUsername": null,
              "operatorNickname": null,
              "totalScore": 70,
              "emailActive": false
            }
          ]
        }
        """.trimIndent()

        val approveResponseJson = """{"code":200,"msg":"已加入白名单","data":null}"""
        val rejectResponseJson = """{"code":200,"msg":"已拒绝申请","data":null}"""
        val removeResponseJson = """{"code":200,"msg":"已从白名单移除","data":null}"""
        val errorResponseJson = """{"code":500,"msg":"操作失败，Rcon连接错误或玩家不存在","data":null}"""
        val authFailJson = """{"code":403,"msg":"无权限：API Key 无效或未提供","data":null}"""

        val fullPlayerJson = """
        {
          "id": 1,
          "playerName": "Steve",
          "uuid": "8667ba71b85a4004af54457a9734eed7",
          "qq": "123456789",
          "status": 1,
          "description": "我是建筑党",
          "createTime": "2026-06-01T12:00:00",
          "regionCode": 110000,
          "regionFullName": "北京市",
          "operatorId": 1,
          "operatorUsername": "admin",
          "operatorNickname": "管理员",
          "totalScore": 85,
          "emailActive": true
        }
        """.trimIndent()

        val playerWithNullOperatorJson = """
        {
          "id": 2,
          "playerName": "Alex",
          "uuid": "def456",
          "qq": "2222222",
          "status": 2,
          "description": "",
          "createTime": "2026-06-03T00:00:00",
          "regionCode": 0,
          "regionFullName": "",
          "operatorId": null,
          "operatorUsername": null,
          "operatorNickname": null,
          "totalScore": 0,
          "emailActive": false
        }
        """.trimIndent()
    }
}
