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

import Foundation
import UIKit
import SnapKit


class LNRoomGiftHeaderView: UIView {
    private let roomSeatsView = UIView()
    private let stackView = UIStackView()
    
    private let specifiedUserView = LNRoomGiftSpecifiedUserView()
    
    private weak var roomSession: LNRoomSession?
    private var headers: [Int: LNRoomGiftAvatarView] = [:]
    var selection: [String] {
        if !roomSeatsView.isHidden {
            headers.map { $1 }.filter { !$0.isHidden && $0.isSelected }.compactMap { $0.curSeatItem?.uid }
        } else if let uid = specifiedUserView.curUid {
            [uid]
        } else {
            []
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupViews()
        LNEventDeliver.addObserver(self)
    }
    
    func update(_ room: LNRoomSession?, selectedUid: String?) {
        roomSession = room
        if selectedUid == nil
            || room?.seatsInfo.contains(where: { $0.uid == selectedUid }) == true {
            if let room {
                onRoomSeatsChanged(session: room, changed: room.seatsInfo)
            }
            
            roomSeatsView.isHidden = false
            specifiedUserView.isHidden = true
        } else {
            roomSeatsView.isHidden = true
            specifiedUserView.isHidden = false
        }
        if let selectedUid {
            headers.first { $1.curSeatItem?.uid == selectedUid }?.value.isSelected = true
            specifiedUserView.update(selectedUid)
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNRoomGiftHeaderView: LNRoomViewModelNotify {
    func onRoomSeatsChanged(session: LNRoomSession, changed: [LNRoomSeatItem]) {
        guard roomSession == session else { return }
        
        guard let seats = roomSession?.seatsInfo.sorted(by: { $0.index < $1.index }) else { return }
        if headers.count != seats.count {
            stackView.arrangedSubviews.forEach {
                stackView.removeArrangedSubview($0)
                $0.removeFromSuperview()
            }
            
            for seat in seats {
                let avatar = LNRoomGiftAvatarView()
                avatar.isSelected = false
                avatar.onTap { [weak avatar] in
                    guard let avatar else { return }
                    avatar.isSelected.toggle()
                }
                avatar.update(seat)
                stackView.addArrangedSubview(avatar)
                headers[seat.index] = avatar
            }
        } else {
            for seat in seats {
                headers[seat.index]?.update(seat)
            }
        }
    }
}

private extension LNRoomGiftHeaderView {
    func setupViews() {
        let titleLabel = UILabel()
        titleLabel.font = .body_l
        titleLabel.textColor = .text_2
        titleLabel.text = .init(key: "B00129")
        addSubview(titleLabel)
        titleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(10)
            make.centerY.equalToSuperview()
        }
        
        let roomSeatsView = buildRoomSeatsView()
        addSubview(roomSeatsView)
        roomSeatsView.snp.makeConstraints { make in
            make.leading.equalTo(titleLabel.snp.trailing).offset(6)
            make.trailing.equalToSuperview().offset(-10)
            make.verticalEdges.equalToSuperview()
            make.height.equalTo(40)
        }
        
        let userView = buildSpecifiedUserView()
        addSubview(userView)
        userView.snp.makeConstraints { make in
            make.leading.equalTo(titleLabel.snp.trailing).offset(6)
            make.trailing.equalToSuperview().offset(-10)
            make.centerY.equalToSuperview()
        }
    }
    
    private func buildRoomSeatsView() -> UIView {
        let scrollView = UIScrollView()
        scrollView.showsHorizontalScrollIndicator = false
        scrollView.contentInset = .init(top: 0, left: 0, bottom: 0, right: 32)
        roomSeatsView.addSubview(scrollView)
        scrollView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        stackView.spacing = 6
        stackView.axis = .horizontal
        scrollView.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
            make.height.equalToSuperview()
        }
        
        let gradientView = UIView.gradientView([
            .fill_7.withAlphaComponent(0), .fill_7
        ], .horizontalLTR)
        roomSeatsView.addSubview(gradientView)
        gradientView.snp.makeConstraints { make in
            make.verticalEdges.equalToSuperview()
            make.trailing.equalToSuperview()
            make.width.equalTo(32)
        }
        
        return roomSeatsView
    }
    
    private func buildSpecifiedUserView() -> UIView {
        
        return specifiedUserView
    }
}

private class LNRoomGiftAvatarView: UIView {
    private let avatarBg = UIView()
    private let avatarView = UIImageView()
    private let badgeBg = UIView()
    private let badge = UILabel()
    private(set) var curSeatItem: LNRoomSeatItem?
    
    var isSelected: Bool = false {
        didSet {
            if isSelected {
                avatarBg.layer.borderColor = UIColor.text_6.cgColor
                badge.textColor = .text_1
                badgeBg.backgroundColor = .text_6
            } else {
                avatarBg.layer.borderColor = UIColor.clear.cgColor
                badge.textColor = .text_4
                badgeBg.backgroundColor = .text_1
            }
        }
    }
    
    func update(_ seat: LNRoomSeatItem) {
        isHidden = seat.uid.isEmpty || seat.uid.isMyUid
        avatarView.sd_setImage(with: URL(string: seat.avatar))
        badge.text = LNOrderRoomSeatNum(rawValue: seat.index)?.giftHeaderTitle
        
        curSeatItem = seat
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        snp.makeConstraints { make in
            make.width.height.equalTo(40)
        }
        
        avatarBg.backgroundColor = .clear
        avatarBg.layer.cornerRadius = 17
        avatarBg.layer.borderWidth = 1
        avatarBg.layer.borderColor = UIColor.primary_4.cgColor
        addSubview(avatarBg)
        avatarBg.snp.makeConstraints { make in
            make.width.height.equalTo(34)
            make.centerX.equalToSuperview()
            make.top.equalToSuperview().offset(1)
            make.bottom.equalToSuperview().offset(-5)
        }
        
        avatarView.layer.cornerRadius = 15
        avatarView.clipsToBounds = true
        avatarView.contentMode = .scaleAspectFill
        avatarBg.addSubview(avatarView)
        avatarView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.width.height.equalTo(30)
        }
        
        badgeBg.backgroundColor = .fill
        badgeBg.layer.cornerRadius = 6
        addSubview(badgeBg)
        badgeBg.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.bottom.equalToSuperview().offset(-2)
            make.height.equalTo(12)
            make.leading.greaterThanOrEqualToSuperview()
            make.width.greaterThanOrEqualTo(26)
        }
        
        badge.font = .systemFont(ofSize: 10)
        badge.textColor = .text_4
        badge.textAlignment = .center
        badgeBg.addSubview(badge)
        badge.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.horizontalEdges.equalToSuperview().inset(4)
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

private class LNRoomGiftSpecifiedUserView: UIView {
    private let nameLabel = UILabel()
    private let avatar = UIImageView()
    private(set) var curUid: String?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        let avatarBg = UIView()
        avatarBg.backgroundColor = .clear
        avatarBg.layer.cornerRadius = 17
        avatarBg.layer.borderWidth = 1
        avatarBg.layer.borderColor = UIColor.primary_4.cgColor
        addSubview(avatarBg)
        avatarBg.snp.makeConstraints { make in
            make.width.height.equalTo(34)
            make.leading.equalToSuperview()
            make.verticalEdges.equalToSuperview()
        }
        
        avatar.layer.cornerRadius = 15
        avatar.clipsToBounds = true
        avatar.contentMode = .scaleAspectFill
        avatarBg.addSubview(avatar)
        avatar.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.width.height.equalTo(30)
        }
        
        nameLabel.font = .body_s
        nameLabel.textColor = .text_1
        addSubview(nameLabel)
        nameLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.leading.equalTo(avatarBg.snp.trailing).offset(5)
            make.trailing.equalToSuperview()
        }
    }
    
    func update(_ uid: String?) {
        curUid = uid
        guard let uid, !uid.isEmpty else {
            isHidden = true
            return
        }
        
        LNProfileManager.shared.getCachedProfileUserInfo(uid: uid, fetchIfNeeded: true)
        { [weak self] info in
            guard let self else { return }
            guard let info, info.uid == curUid else { return }
            nameLabel.text = info.name
            avatar.sd_setImage(with: URL(string: info.avatar))
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
