import Foundation
import UIKit
import Combine

protocol UNSnapshotProtectionServicing {
    func start(shouldProtect: Bool, style: String)
}

class UNSnapshotProtectionService: UNSnapshotProtectionServicing {
    fileprivate var subscribers = Set<AnyCancellable>()

    private lazy var blurEffectView: UIVisualEffectView = {

        let blurEffect = UIBlurEffect(style: .light)
        var blurEffectView = UIVisualEffectView(effect: blurEffect)

        return blurEffectView
    }()

    func start(shouldProtect: Bool, style: String) {
       if shouldProtect {
          removeObservers()
          setupObservers()
       } else {
          removeObservers()
          removeBlurEffect()
       }

       updateBlurEffect(style)
    }

    private func updateBlurEffect(_ style: String) {
       DispatchQueue.main.async { [weak self] in
           guard let self = self else { return }
           switch style {
           case "dark":
               self.blurEffectView.effect = UIBlurEffect(style: .dark)
           default:
               self.blurEffectView.effect = UIBlurEffect(style: .light)
           }
       }
   }
}


fileprivate extension UNSnapshotProtectionService {
    func addBlurEffect() {
        DispatchQueue.main.async { [weak self] in
            guard let self = self,
                 let topViewController = UNPresentationService().requestTopController() else { return }

            topViewController.view.addSubview(self.blurEffectView)
            topViewController.view.bringSubviewToFront(self.blurEffectView)

                self.blurEffectView.translatesAutoresizingMaskIntoConstraints = false

                NSLayoutConstraint.activate([
                    self.blurEffectView.topAnchor.constraint(equalTo: topViewController.view.topAnchor),
                    self.blurEffectView.bottomAnchor.constraint(equalTo: topViewController.view.bottomAnchor),
                    self.blurEffectView.leadingAnchor.constraint(equalTo: topViewController.view.leadingAnchor),
                    self.blurEffectView.trailingAnchor.constraint(equalTo: topViewController.view.trailingAnchor)
                ])
        }
    }

    func removeBlurEffect() {
        DispatchQueue.main.async { [weak self] in
            guard let self else { return }
            if let _ = self.blurEffectView.superview {
                self.blurEffectView.removeFromSuperview()
            }
        }
    }
}

fileprivate extension UNSnapshotProtectionService {
    func setupObservers() {
        UNSharedServicesProvider.shared.appStateService().appStateStatusPublisher
            .receive(on: DispatchQueue.main)
            .sink { [weak self] appStateStatus in
                guard let self = self else { return }
                switch appStateStatus {
                case .appDidBecomeActive:
                    self.removeBlurEffect()
                case .appWillResignActive:
                    self.addBlurEffect()
                }
            }
            .store(in: &subscribers)
    }

    func removeObservers() {
        subscribers.forEach { $0.cancel() }
        subscribers.removeAll()
    }
}
