//
//  IncomingFloatView.swift
//  TUICallKit-Swift
//
//  Created by noah on 2024/3/15.
//

import UIKit
import SnapKit

class IncomingFloatView: UIView {
    
    let remoteUserListObserver = Observer()
    let mediaTypeObserver = Observer()
    
    let userHeadImageView: UIImageView = {
        let userHeadImageView = UIImageView(frame: CGRect.zero)
        userHeadImageView.layer.masksToBounds = true
        userHeadImageView.layer.cornerRadius = 7.0
        if let image = TUICallKitCommon.getBundleImage(name: "default_user_icon") {
            userHeadImageView.image = image
        }
        return userHeadImageView
    }()
    
    let userNameLabel: UILabel = {
        let userNameLabel = UILabel(frame: CGRect.zero)
        userNameLabel.textColor = UIColor.t_colorWithHexString(color: "#D5E0F2")
        userNameLabel.font = UIFont.boldSystemFont(ofSize: 18.0)
        userNameLabel.backgroundColor = UIColor.clear
        userNameLabel.textAlignment = .center
        return userNameLabel
    }()
    
    let callStatusTipView: UILabel = {
        let callStatusTipLabel = UILabel(frame: CGRect.zero)
        callStatusTipLabel.textColor = UIColor.t_colorWithHexString(color: "#C5CCDB")
        callStatusTipLabel.font = UIFont.boldSystemFont(ofSize: 12.0)
        callStatusTipLabel.textAlignment = .left
        return callStatusTipLabel
    }()
    
    lazy var rejectBtn: UIButton = {
        let btn = UIButton(type: .system)
        if let image = TUICallKitCommon.getBundleImage(name: "icon_hangup") {
            btn.setBackgroundImage(image, for: .normal)
        }
        btn.addTarget(self, action: #selector(rejectTouchEvent(sender: )), for: .touchUpInside)
        return btn
    }()
    
    lazy var acceptBtn: UIButton = {
        let btn = UIButton(type: .system)
        let imageStr = TUICallState.instance.mediaType.value == .video ? "icon_video_dialing" : "icon_dialing"
        if let image = TUICallKitCommon.getBundleImage(name: imageStr) {
            btn.setBackgroundImage(image, for: .normal)
        }
        btn.addTarget(self, action: #selector(acceptTouchEvent(sender: )), for: .touchUpInside)
        return btn
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        userHeadImageView.layer.masksToBounds = true
        self.layer.cornerRadius = 10.0
        backgroundColor = UIColor.t_colorWithHexString(color: "#22262E")
        let tap = UITapGestureRecognizer(target: self, action: #selector(showCallView(sender:)))
        self.addGestureRecognizer(tap)
        callStatusTipView.text = getCallStatusTipText()
        registerObserveState()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        TUICallState.instance.remoteUserList.removeObserver(remoteUserListObserver)
        TUICallState.instance.mediaType.removeObserver(mediaTypeObserver)
    }
    
    // MARK: UI Specification Processing
    private var isViewReady: Bool = false
    override func didMoveToWindow() {
        super.didMoveToWindow()
        if isViewReady { return }
        constructViewHierarchy()
        activateConstraints()
        isViewReady = true
    }
    
    func constructViewHierarchy() {
        addSubview(userHeadImageView)
        addSubview(userNameLabel)
        addSubview(callStatusTipView)
        addSubview(rejectBtn)
        addSubview(acceptBtn)
    }
    
    func activateConstraints() {
        self.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        userHeadImageView.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(16.scaleWidth())
            make.centerY.equalTo(self)
            make.width.height.equalTo(60.scaleWidth())
        }
        userNameLabel.snp.makeConstraints { make in
            make.top.equalTo(userHeadImageView).offset(10.scaleWidth())
            make.leading.equalTo(userHeadImageView.snp.trailing).offset(12.scaleWidth())
        }
        callStatusTipView.snp.makeConstraints { make in
            make.leading.equalTo(userHeadImageView.snp.trailing).offset(12.scaleWidth())
            make.bottom.equalTo(userHeadImageView).offset(-10.scaleWidth())
        }
        rejectBtn.snp.makeConstraints { make in
            make.trailing.equalTo(acceptBtn.snp.leading).offset(-22.scaleWidth())
            make.centerY.equalTo(self)
            make.width.height.equalTo(36.scaleWidth())
        }
        acceptBtn.snp.makeConstraints { make in
            make.trailing.equalToSuperview().offset(-16.scaleWidth())
            make.centerY.equalTo(self)
            make.width.height.equalTo(36.scaleWidth())
        }
    }
    
    // MARK: Event Action
    @objc func showCallView(sender: UIButton) {
        self.removeFromSuperview()
        WindowManager.instance.showCallWindow(false)
    }
    
    @objc func rejectTouchEvent(sender: UIButton) {
        self.removeFromSuperview()
        CallEngineManager.instance.reject()
    }
    
    @objc func acceptTouchEvent(sender: UIButton) {
        self.removeFromSuperview()
        CallEngineManager.instance.accept()
    }
    
    // MARK: Register TUICallState Observer && Update UI
    func registerObserveState() {
        remoteUserListChanged()
        mediaTypeChanged()
    }
    
    func remoteUserListChanged() {
        TUICallState.instance.remoteUserList.addObserver(remoteUserListObserver, closure: { [weak self] newValue, _ in
            guard let self = self else { return }
            self.setUserImageAndName()
        })
    }
    
    func mediaTypeChanged() {
        TUICallState.instance.mediaType.addObserver(mediaTypeObserver, closure: { [weak self] newValue, _ in
            guard let self = self else { return }
            self.callStatusTipView.text = self.getCallStatusTipText()
        })
    }
    
    func setUserImageAndName() {
        let remoteUser = TUICallState.instance.remoteUserList.value.first ?? User()
        userNameLabel.text = User.getUserDisplayName(user: remoteUser)
        
        if let url = URL(string: remoteUser.avatar.value) {
            userHeadImageView.sd_setImage(with: url)
        }
    }
    
    func getCallStatusTipText() -> String {
        if TUICallState.instance.scene.value == .group {
            return TUICallKitLocalize(key: "TUICallKit.Group.inviteToGroupCall") ?? ""
        }
        
        var tipLabelText = String()
        switch TUICallState.instance.mediaType.value {
        case .audio:
            tipLabelText = TUICallKitLocalize(key: "TUICallKit.inviteToAudioCall") ?? ""
        case .video:
            tipLabelText = TUICallKitLocalize(key: "TUICallKit.inviteToVideoCall") ?? ""
        case .unknown:
            break
        default:
            break
        }
        return tipLabelText
    }
}
