//
//  LNAudioCallFloatingView.swift
//  Gami
//
//  Created by OneeChan on 2026/2/3.
//

import Foundation
import UIKit
import SnapKit


class LNAudioCallFloatingView: UIView {
    private let size: CGFloat = 67
    
    private let stackView = UIStackView()
    private let stateIc = UIImageView()
    private let durationLabel = UILabel()
    
    private var timer: Timer?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupViews()
        setupGesture()
        
        LNEventDeliver.addObserver(self)
        
        if let callInfo = LNIMManager.shared.curCallInfo,
           callInfo.beginTime > 0 {
            updateCallDuration()
            startTimer()
        }
    }
    
    func show() {
        guard let window = UIView.appKeyWindow else { return }
        window.addSubview(self)
        
        frame = .init(x: window.bounds.width - 16 - size,
                      y: window.bounds.height - 100.0 - size,
                      width: size, height: size)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension LNAudioCallFloatingView {
    func dismiss() {
        removeFromSuperview()
    }
    
    private func updateCallDuration() {
        guard let callInfo = LNIMManager.shared.curCallInfo else { return }
        let duration = curTime - callInfo.beginTime
        durationLabel.text = duration.timeCountDisplay
        durationLabel.isHidden = false
    }
    
    private func startTimer() {
        stopTimer()
        let timer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [weak self] _ in
            guard let self else { return }
            guard LNIMManager.shared.curCallInfo != nil else {
                stopTimer()
                return
            }
            
            updateCallDuration()
        }
        RunLoop.main.add(timer, forMode: .common)
        self.timer = timer
    }
    
    private func stopTimer() {
        timer?.invalidate()
        timer = nil
    }
}

extension LNAudioCallFloatingView {
    @objc
    private func handlePan(_ ges: UIPanGestureRecognizer) {
        let location = ges.location(in: superview)
        
        switch ges.state {
        case .began:
            break
        case .changed:
            center = location
            break
        default:
            updatePosition(animated: true)
            break
        }
    }
}

extension LNAudioCallFloatingView {
    private func updatePosition(animated: Bool) {
        guard let superview else { return }
        let movement = { [weak self] in
            guard let self else { return }
            
            let y = center.y.bounded(min: 160, max: superview.bounds.height - 160)
//            if center.x > superview.bounds.width * 0.5 {
                center = .init(x: superview.bounds.width - bounds.width * 0.5 - 16, y: y)
//            } else {
//                center = .init(x: bounds.width * 0.5 + 16, y: y)
//            }
        }
        if animated {
            UIView.animate(withDuration: 0.25, animations: movement)
        } else {
            movement()
        }
    }
    
    private func setupViews() {
        layer.shadowColor = UIColor.black.withAlphaComponent(0.08).cgColor
        layer.shadowOffset = .init(width: 0, height: 4)
        layer.shadowRadius = 6
        layer.shadowOpacity = 0.5
        layer.masksToBounds = false
        
        backgroundColor = .fill
        layer.cornerRadius = 12
        
        stackView.axis = .vertical
        stackView.spacing = 8
        stackView.alignment = .center
        addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.center.equalToSuperview()
        }
        
        stateIc.image = .icCalling
        stackView.addArrangedSubview(stateIc)
        
        durationLabel.isHidden = true
        durationLabel.font = .heading_h5
        durationLabel.textColor = .text_6
        stackView.addArrangedSubview(durationLabel)
    }
    
    private func setupGesture() {
        let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:)))
        addGestureRecognizer(pan)
        
        onTap {
            let panel = LNAudioCallPanel()
            panel.resume()
            panel.popup()
        }
    }
}

extension LNAudioCallFloatingView: LNIMManagerNotify {
    func onVoiceCallEnd() {
        dismiss()
    }
    
    func onVoiceCallBegin() {
        updateCallDuration()
        startTimer()
    }
}
