import Photos
import PhotosUI

public func requestCameraPermissionIfNeeded() -> Bool {
    switch AVCaptureDevice.authorizationStatus(for: .video) {
    case .authorized: return true
    case .denied, .restricted:
        let modal = PermissionMissingModal(permission: "camera") { }
        modal.modalPresentationStyle = .overFullScreen
        modal.modalTransitionStyle = .crossDissolve
        guard let presentingVC = CurrentAppContext().frontmostViewController() else { preconditionFailure() }
        presentingVC.present(modal, animated: true, completion: nil)
        return false
    case .notDetermined:
        AVCaptureDevice.requestAccess(for: .video, completionHandler: { _ in })
        return false
    default: return false
    }
}

public func requestMicrophonePermissionIfNeeded(onNotGranted: @escaping () -> Void) {
    switch AVAudioSession.sharedInstance().recordPermission {
    case .granted: break
    case .denied:
        onNotGranted()
        let modal = PermissionMissingModal(permission: "microphone") {
            onNotGranted()
        }
        modal.modalPresentationStyle = .overFullScreen
        modal.modalTransitionStyle = .crossDissolve
        guard let presentingVC = CurrentAppContext().frontmostViewController() else { preconditionFailure() }
        presentingVC.present(modal, animated: true, completion: nil)
    case .undetermined:
        onNotGranted()
        AVAudioSession.sharedInstance().requestRecordPermission { _ in }
    default: break
    }
}

public func requestLibraryPermissionIfNeeded(onAuthorized: @escaping () -> Void) {
    let authorizationStatus: PHAuthorizationStatus
    if #available(iOS 14, *) {
        authorizationStatus = PHPhotoLibrary.authorizationStatus(for: .readWrite)
        if authorizationStatus == .notDetermined {
            // When the user chooses to select photos (which is the .limit status),
            // the PHPhotoUI will present the picker view on the top of the front view.
            // Since we have the ScreenLockUI showing when we request premissions,
            // the picker view will be presented on the top of the ScreenLockUI.
            // However, the ScreenLockUI will dismiss with the permission request alert view, so
            // the picker view then will dismiss, too. The selection process cannot be finished
            // this way. So we add a flag (isRequestingPermission) to prevent the ScreenLockUI
            // from showing when we request the photo library permission.
            Environment.shared.isRequestingPermission = true
            let appMode = AppModeManager.shared.currentAppMode
            // FIXME: Rather than setting the app mode to light and then to dark again once we're done,
            // it'd be better to just customize the appearance of the image picker. There doesn't currently
            // appear to be a good way to do so though...
            AppModeManager.shared.setCurrentAppMode(to: .light)
            PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in
                DispatchQueue.main.async {
                    AppModeManager.shared.setCurrentAppMode(to: appMode)
                }
                Environment.shared.isRequestingPermission = false
                if [ PHAuthorizationStatus.authorized, PHAuthorizationStatus.limited ].contains(status) {
                    onAuthorized()
                }
            }
        }
    } else {
        authorizationStatus = PHPhotoLibrary.authorizationStatus()
        if authorizationStatus == .notDetermined {
            PHPhotoLibrary.requestAuthorization { status in
                if status == .authorized {
                    onAuthorized()
                }
            }
        }
    }
    switch authorizationStatus {
    case .authorized, .limited:
        onAuthorized()
    case .denied, .restricted:
        let modal = PermissionMissingModal(permission: "library") { }
        modal.modalPresentationStyle = .overFullScreen
        modal.modalTransitionStyle = .crossDissolve
        guard let presentingVC = CurrentAppContext().frontmostViewController() else { preconditionFailure() }
        presentingVC.present(modal, animated: true, completion: nil)
    default: return
    }
}