//
//  LNRoomPushMessage.swift
//  Gami
//
//  Created by OneeChan on 2026/3/20.
//

import Foundation
import AtomicXCore
import AutoCodable


enum LNRoomSystemMessageType: String, CaseIterable {
    case welcome = "local.welcome"
    case MicClear = "mic.clear"
    case RoomGift = "room.gift"
}


@AutoCodable
class LNRoomMicClearMessage: Decodable {
    var type: LNOrderRoomApplyingSeatType = .none
    var time: Int64 = 0
}


@AutoCodable
class LNRoomGiftUserInfo: Decodable {
    var nickname: String = ""
}

@AutoCodable
class LNRoomGiftMessage: Decodable {
    var quantity: Int = 0
    var sender: String = ""
    var receivers: [String] = []
    var resId: String = ""
    var users: [String: LNRoomGiftUserInfo] = [:]
}

class LNRoomPushMessage {
    let innerMessage: Barrage
    let cmd: LNRoomSystemMessageType
    private var cmdMessage: (any Decodable)?
    
    var messageItems: [LNRoomMessageItem]? {
        var list: [LNRoomMessageItem] = []
        
        switch cmd {
        case .welcome:
            let item = LNRoomWelcomeMessageItem()
            item.userNo = innerMessage.sender.userID
            item.nickname = innerMessage.sender.userName
            list.append(item)
        case .RoomGift:
            if let messages: [LNRoomGiftMessage] = decodeCmdMessage() {
                var needUpdate = false
                for message in messages {
                    for user in message.receivers {
                        let item = LNRoomGiftMessageItem()
                        item.sender = message.sender
                        item.senderName = message.users[message.sender]?.nickname ?? ""
                        
                        if let giftRes = LNGiftManager.shared.resource(for: message.resId) {
                            item.giftName = giftRes.curName
                            item.giftIcon = giftRes.icon
                        } else {
                            needUpdate = true
                        }
                        item.giftCount = message.quantity
                        
                        item.receiver = user
                        item.receiverName = message.users[user]?.nickname ?? ""
                        list.append(item)
                    }
                }
                if needUpdate {
                    LNGiftManager.shared.updateGiftResource()
                }
            }
        case .MicClear:
            break
        }
        
        return list
    }
    
    init?(info: Barrage) {
        guard info.messageType == .custom,
              let type = LNRoomSystemMessageType(rawValue: info.businessID)
        else { return nil }
        innerMessage = info
        cmd = type
    }
    
    func decodeCmdMessage<T: Decodable>() -> T? {
        if let cached = cmdMessage as? T {
            return cached
        }
        
        guard let data = innerMessage.data.data(using: .utf8) else { return nil }
        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .useDefaultKeys
        let result = try? decoder.decode(T.self, from: data)
        if let result {
            cmdMessage = result
        }
        return result
    }
}
