//
//  LNOrderRoomUserSeatView.swift
//  Gami
//
//  Created by OneeChan on 2026/3/23.
//

import Foundation
import UIKit
import SnapKit


class LNOrderRoomUserSeatView: UIView {
    private let seatNum: LNOrderRoomSeatNum
    private let nameLabel = UILabel()
    private let emptyIc = UIImageView()
    private var emptyIcon: UIImage {
        switch seatNum {
        case .host: .icSeatNormal
        case .guest: .icSeatGuest
        default: .icSeatNormal
        }
    }
    
    private let userView = UIView()
    private let userAvatar = UIImageView()
    private let muteIc = UIImageView()
    private let speakingView = LNRoomSeatSpeakingView()
    
    private weak var roomSession: LNOrderRoomViewModel?
    private var curSeat: LNRoomSeatItem? {
        roomSession?.seatsInfo.first { $0.index == seatNum.rawValue }
    }
    private var isSpeaking: Bool {
        roomSession?.speakingUser.contains(curSeat?.uid ?? "") == true
    }
    
    init(seatNum: LNOrderRoomSeatNum) {
        self.seatNum = seatNum
        super.init(frame: .zero)
        
        setupViews()
        LNEventDeliver.addObserver(self)
    }
    
    func update(_ room: LNOrderRoomViewModel?) {
        roomSession = room
        if let room {
            onRoomSeatsChanged(session: room, changed: room.seatsInfo)
            speakingView.update(seatNum.rawValue, room: room)
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNOrderRoomUserSeatView {
    private func handlerClick() {
        guard let room = roomSession, let seat = curSeat else { return }
        guard let orderSeatNum = LNOrderRoomSeatNum(rawValue: seat.index) else { return }
        let mySeatNum = LNOrderRoomSeatNum(rawValue: room.mySeatInfo?.index ?? -1) ?? .none
        
        let sheet = LNRoomSheetMenu()
        
        let invite = LNRoomSheetMenu.buildMenuItem(title: .init(key: "A00341"), handler: { [weak sheet, weak self] in
            guard let self, let sheet else { return }
            sheet.dismiss()
            
            let panel = LNOrderRoomInviteSeatPanel()
            panel.update(seat, room: room)
            panel.popup(self)
        })
        
        let closeMic = LNRoomSheetMenu.buildMenuItem(title: .init(key: "A00342"), handler: { [weak sheet] in
            guard let sheet else { return }
            room.lockSeat(num: seat.index) { [weak sheet] success in
                guard let sheet else { return }
                guard success else { return }
                sheet.dismiss()
            }
        })
        
        let openMic = LNRoomSheetMenu.buildMenuItem(title: .init(key: "A00348"), handler: { [weak sheet] in
            guard let sheet else { return }
            room.unlockSeat(num: seat.index) { [weak sheet] success in
                guard let sheet else { return }
                guard success else { return }
                sheet.dismiss()
            }
        })
        
        let muteMic = LNRoomSheetMenu.buildMenuItem(title: .init(key: "A00343"), handler: { [weak sheet] in
            guard let sheet else { return }
            sheet.dismiss()
            
            room.muteSeat(uid: seat.uid) { _ in }
        })
        
        let unmuteMic = LNRoomSheetMenu.buildMenuItem(title: .init(key: "A00349"), handler: { [weak sheet] in
            guard let sheet else { return }
            sheet.dismiss()
            
            room.unmuteSeat(uid: seat.uid) { _ in }
        })
        
        let profile = LNRoomSheetMenu.buildMenuItem(title: .init(key: "A00344"), handler: { [weak sheet] in
            guard let sheet else { return }
            sheet.dismiss()
            
            let panel = LNRoomProfileCardPanel()
            panel.load(seat.uid)
            panel.popup(self)
        })
        
        let kickOffMic = LNRoomSheetMenu.buildMenuItem(title: .init(key: "A00345"), handler: { [weak sheet] in
            guard let sheet else { return }
            room.kickUserOffSeat(uid: seat.uid) { [weak sheet] success in
                guard let sheet else { return }
                guard success else { return }
                sheet.dismiss()
            }
        })
        
        let offMic = LNRoomSheetMenu.buildMenuItem(title: .init(key: "A00346"), handler: { [weak sheet] in
            guard let sheet else { return }
            room.leaveSeat { [weak sheet] success in
                guard let sheet else { return }
                guard success else { return }
                sheet.dismiss()
            }
        })
        
        let toBePlaymate = LNRoomSheetMenu.buildMenuItem(title: .init(key: "A00347"), handler: { [weak sheet] in
            guard let sheet else { return }
            showLoading()
            LNGameMateManager.shared.getJoinGameMateInfo { [weak sheet] res in
                dismissLoading()
                guard let sheet else { return }
                guard let res else { return }
                sheet.dismiss()
                
                if res.step3Complete || res.underReview {
                    sheet.pushToJoinUsReview(true)
                    return
                }
                let config = LNJumpWebViewConfig(url: .joinUsUrl)
                sheet.pushToWebView(config)
            }
        })
        
        if seat.uid.isMyUid { // 自己
            sheet.update(title: nil, views: [
                offMic, profile
            ])
        } else if room.mySeatInfo?.index == LNOrderRoomSeatNum.host.rawValue { // 管理员
            if seat.uid.isEmpty { // 空麦位
                if seat.isLocked {
                    sheet.update(title: orderSeatNum.title, views: [
                        openMic
                    ])
                } else {
                    sheet.update(title: orderSeatNum.title, views: [
                        invite, closeMic
                    ])
                }
            } else { // 有人的麦位
                sheet.update(title: orderSeatNum.title, views: [
                    profile, kickOffMic, closeMic, seat.isMute ? unmuteMic : muteMic
                ])
            }
        } else {
            if seat.isLocked { return } // 麦位被锁，仅管理员能操作
            
            if !seat.uid.isEmpty { // 有人的麦位
                let panel = LNRoomProfileCardPanel()
                panel.load(seat.uid)
                panel.popup(self)
                return
            }
            
            if myUserInfo.playmate { // 陪玩师
                if orderSeatNum == .host
                    || orderSeatNum == .guest
                    || !(.mic1 ... .mic8 ~= mySeatNum) {
                    let panel = LNOrderRoomApplySeatPanel()
                    panel.update(room, seat: orderSeatNum)
                    panel.popup(self)
                    return
                }
                return
            } else { // 普通用户
                if orderSeatNum == .host || orderSeatNum == .guest { // 主持人 和 嘉宾位
                    let panel = LNOrderRoomApplySeatPanel()
                    panel.update(room, seat: orderSeatNum)
                    panel.popup(self)
                    return
                } else {
                    sheet.update(title: nil, views: [
                        toBePlaymate
                    ])
                }
            }
        }
        
        sheet.popup(self)
    }
}

extension LNOrderRoomUserSeatView: LNRoomViewModelNotify {
    func onRoomSeatsChanged(session: LNRoomSession, changed: [LNRoomSeatItem]) {
        guard roomSession == session else { return }
        guard let curSeat else { return }
        
        if curSeat.isLocked {
            userView.isHidden = true
            emptyIc.image = .icSeatLock
            
            nameLabel.text = seatNum.title
        } else if curSeat.uid.isEmpty {
            userView.isHidden = true
            emptyIc.image = emptyIcon
            
            nameLabel.text = seatNum.title
        } else {
            userView.isHidden = false
            
            if !curSeat.nickname.isEmpty {
                userAvatar.sd_setImage(with: URL(string: curSeat.avatar))
                nameLabel.text = curSeat.nickname
            } else {
                LNProfileManager.shared.getCachedProfileUserInfo(uid: curSeat.uid) { [weak self] info in
                    guard let self, let info, info.uid == curSeat.uid else { return }
                    userAvatar.sd_setImage(with: URL(string: info.avatar))
                    nameLabel.text = info.name
                }
            }
        }
        
        muteIc.isHidden = !curSeat.isMute
    }
}

extension LNOrderRoomUserSeatView {
    private func setupViews() {
        onTap { [weak self] in
            guard let self else { return }
            handlerClick()
        }
        snp.makeConstraints { make in
            make.width.equalTo(76)
            make.height.equalTo(68)
        }
        
        let empty = buildEmpty()
        addSubview(empty)
        empty.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.top.equalToSuperview()
        }
        
        let userView = buildUserView()
        addSubview(userView)
        userView.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.top.equalToSuperview()
        }
        
        let bottom = buildBottom()
        addSubview(bottom)
        bottom.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.bottom.equalToSuperview()
            make.leading.greaterThanOrEqualToSuperview()
        }
    }
    
    private func buildEmpty() -> UIView {
        emptyIc.image = .icSeatNormal
        
        return emptyIc
    }
    
    private func buildUserView() -> UIView {
        userView.isHidden = true
        userView.snp.makeConstraints { make in
            make.width.height.equalTo(46)
        }
        
        userView.addSubview(speakingView)
        speakingView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        let gradientBg = UIImageView()
        gradientBg.layer.cornerRadius = 23
        gradientBg.image = .primary_7
        gradientBg.clipsToBounds = true
        userView.addSubview(gradientBg)
        gradientBg.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        userAvatar.layer.cornerRadius = 22
        userAvatar.clipsToBounds = true
        userView.addSubview(userAvatar)
        userAvatar.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.width.height.equalTo(44)
        }
        
        muteIc.image = .icMicOffBlack70
        userView.addSubview(muteIc)
        muteIc.snp.makeConstraints { make in
            make.trailing.equalToSuperview()
            make.bottom.equalToSuperview()
        }
        
        return userView
    }
    
    private func buildBottom() -> UIView {
        let stackView = UIStackView()
        stackView.spacing = 2
        stackView.alignment = .center
        
        let hostIc = UIImageView(image: .icMicRoomHost)
        hostIc.isHidden = seatNum != .host
        stackView.addArrangedSubview(hostIc)
        
        nameLabel.font = .body_xs
        nameLabel.textColor = .text_1
        nameLabel.textAlignment = .center
        stackView.addArrangedSubview(nameLabel)
        
        return stackView
    }
}
