//
//  BaseActionSheet.swift

//
//  Created by Leon on 2025/7/17.
//

import UIKit

// MARK: - Enums

enum EGPopViewDirection: Int {
    case top
    case left
    case right
    case bottom
}

// MARK: - Protocols

protocol EGPopViewDelegate: AnyObject {
    func popViewWillAppear(_ view: EGPopBaseView)
    func popViewDidAppear(_ view: EGPopBaseView)
    func popViewWillDisappear(_ view: EGPopBaseView)
    func popViewDidDisappear(_ view: EGPopBaseView)
}

extension EGPopViewDelegate {
    func popViewWillAppear(_ view: EGPopBaseView) {}
    func popViewDidAppear(_ view: EGPopBaseView) {}
    func popViewWillDisappear(_ view: EGPopBaseView) {}
    func popViewDidDisappear(_ view: EGPopBaseView) {}
}

// MARK: - Main Class

class EGPopBaseView: UIView {
    // MARK: - Properties
    private var effectView: UIVisualEffectView
    private var backgroundView: UIButton
    private(set) var contentView: UIView
    private var direction: EGPopViewDirection
    
    /// has value when keyboard show!
    public var bottomKeyboardHeight: CGFloat = 0
    
    weak var delegate: EGPopViewDelegate?
    
    var bgAlpha: CGFloat = 0.6 {
        didSet {
            backgroundView.alpha = dimBg ? bgAlpha : 0
        }
    }
    
    var bgColor: UIColor = .black {
        didSet {
            backgroundView.backgroundColor = bgColor
        }
    }
    
    var dimBg: Bool = true {
        didSet {
            backgroundView.alpha = dimBg ? bgAlpha : 0
        }
    }
    
    var blurBg: Bool = false {
        didSet {
            effectView.effect = blurBg ? UIBlurEffect(style: .extraLight) : nil
        }
    }
    
    public var contentLength: CGFloat = 0 {
        didSet {
            layoutContentViewToHide()
        }
    }
    
    var contentInsets: UIEdgeInsets = .zero {
        didSet {
            layoutContentViewToHide()
        }
    }
    
    var animateDuration: CGFloat = 0.4
    
    // MARK: - Initialization
    init(direction: EGPopViewDirection) {
        self.direction = direction
        self.effectView = UIVisualEffectView(effect: nil)
        self.backgroundView = UIButton(type: .custom)
        self.contentView = UIView()
        super.init(frame: .zero)
        
        backgroundColor = .clear
        setupEffectView()
        setupBackgroundView()
        setupContentViewForDirection(direction)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupEffectView() {
        effectView.frame = UIScreen.main.bounds
        addSubview(effectView)
    }
    
    private func setupBackgroundView() {
        bgColor = .black.withAlphaComponent(1) // Replace with EPSystemToken equivalent
        backgroundView.addTarget(self, action: #selector(bgButtonPressed(_:)), for: .touchUpInside)
        backgroundView.frame = UIScreen.main.bounds
        backgroundView.backgroundColor = bgColor
        backgroundView.alpha = 0
        addSubview(backgroundView)
    }
    
    private func setupContentViewForDirection(_ direction: EGPopViewDirection) {
        contentView.backgroundColor = .white
        contentView.layer.cornerRadius = 32
        contentView.layer.masksToBounds = true
        contentView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
        addSubview(contentView)
        
        switch direction {
        case .top, .bottom:
            contentLength = UIScreen.main.bounds.height / 3
        case .left, .right:
            contentLength = UIScreen.main.bounds.width / 3
        }
    }
    
    // MARK: - Data
    func setContentLength(_ length: CGFloat) {
        contentLength = length
    }
    
    // MARK: - Events
    @objc func bgButtonPressed(_ button: UIButton) {
        dismiss()
    }
    
    // MARK: - Layout
    func layoutInWindow() {
        guard let window =  UIWindow.getTopDisplayWindow() else { return }
        window.endEditing(true)
        window.addSubview(self)
        self.frame = window.bounds
    }
    
    private func layoutContentViewToHide() {
        let screenWidth = UIScreen.main.bounds.width
        let screenHeight = UIScreen.main.bounds.height
        
        switch direction {
        case .top:
            contentView.frame = CGRect(
                x: contentInsets.left,
                y: -(contentLength + contentInsets.top),
                width: screenWidth - (contentInsets.left + contentInsets.right),
                height: contentLength
            )
        case .bottom:
            contentView.frame = CGRect(
                x: contentInsets.left,
                y: screenHeight + contentInsets.bottom,
                width: screenWidth - (contentInsets.left + contentInsets.right),
                height: contentLength
            )
        case .left:
            contentView.frame = CGRect(
                x: -(contentLength + contentInsets.left),
                y: contentInsets.top,
                width: contentLength,
                height: screenHeight - (contentInsets.top + contentInsets.bottom)
            )
        case .right:
            contentView.frame = CGRect(
                x: screenWidth + contentInsets.right,
                y: contentInsets.top,
                width: contentLength,
                height: screenHeight - (contentInsets.top + contentInsets.bottom)
            )
        }
    }
    
    private func layoutContentViewToDisplay() {
        let screenWidth = UIScreen.main.bounds.width
        let screenHeight = UIScreen.main.bounds.height
        
        switch direction {
        case .top:
            contentView.frame = CGRect(
                x: contentInsets.left,
                y: contentInsets.top,
                width: screenWidth - (contentInsets.left + contentInsets.right),
                height: contentLength
            )
        case .bottom:
            contentView.frame = CGRect(
                x: contentInsets.left,
                y: screenHeight - contentLength - contentInsets.bottom - bottomKeyboardHeight,
                width: screenWidth - (contentInsets.left + contentInsets.right),
                height: contentLength
            )
        case .left:
            contentView.frame = CGRect(
                x: contentInsets.left,
                y: contentInsets.top,
                width: contentLength,
                height: screenHeight - (contentInsets.top + contentInsets.bottom)
            )
        case .right:
            contentView.frame = CGRect(
                x: screenWidth - contentLength - contentInsets.right,
                y: contentInsets.top,
                width: contentLength,
                height: screenHeight - (contentInsets.top + contentInsets.bottom)
            )
        }
    }
    
    // MARK: - Animation
    func showWithAnimation() {
        delegate?.popViewWillAppear(self)
        
        UIView.animate(withDuration: TimeInterval(animateDuration), delay: 0, options: .curveEaseInOut) { [weak self] in
            guard let self = self else { return }
            if self.dimBg {
                self.backgroundView.alpha = self.bgAlpha
            }
            if self.blurBg {
                self.effectView.effect = UIBlurEffect(style: .extraLight)
            }
            self.layoutContentViewToDisplay()
        } completion: { [weak self] finished in
            guard let self = self else { return }
            self.delegate?.popViewDidAppear(self)
        }
    }
    
    func dismissWithAnimation() {
        delegate?.popViewWillDisappear(self)
        
        UIView.animate(withDuration: TimeInterval(animateDuration), delay: 0, options: .curveEaseInOut) { [weak self] in
            guard let self = self else { return }
            if self.dimBg {
                self.backgroundView.alpha = 0
            }
            if self.blurBg {
                self.effectView.effect = nil
            }
            self.layoutContentViewToHide()
        } completion: { [weak self] finished in
            guard let self = self else { return }
            self.delegate?.popViewDidDisappear(self)
            self.removeFromSuperview()
        }
    }
    
    // MARK: - Display
    func show() {
        layoutInWindow()
        showWithAnimation()
    }
    
    func dismiss() {
        dismissWithAnimation()
    }
    
    func refreshLPositon(){
        layoutContentViewToDisplay()
    }
    
    static func hideAllPopView() {
        guard let window = UIWindow.getTopDisplayWindow() else { return }
        for subview in window.subviews {
            if let popView = subview as? EGPopBaseView {
                popView.isHidden = true
                popView.removeFromSuperview()
            }
        }
    }
}
