// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.

import UIKit
import Photos
import PhotosUI
import SessionUIKit
import SessionUtilitiesKit
import SessionMessagingKit

public enum Permissions {
    @discardableResult public static func requestCameraPermissionIfNeeded(
        presentingViewController: UIViewController? = nil,
        onAuthorized: (() -> Void)? = nil
    ) -> Bool {
        switch AVCaptureDevice.authorizationStatus(for: .video) {
            case .authorized:
                onAuthorized?()
                return true
            
            case .denied, .restricted:
                guard let presentingViewController: UIViewController = (presentingViewController ?? CurrentAppContext().frontmostViewController()) else { return false }
                
                let confirmationModal: ConfirmationModal = ConfirmationModal(
                    info: ConfirmationModal.Info(
                        title: "Session",
                        body: .text(
                            String(
                                format: "modal_permission_explanation".localized(),
                                "modal_permission_camera".localized()
                            )
                        ),
                        confirmTitle: "modal_permission_settings_title".localized(),
                        dismissOnConfirm: false
                    ) { [weak presentingViewController] _ in
                        presentingViewController?.dismiss(animated: true, completion: {
                            UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
                        })
                    }
                )
                presentingViewController.present(confirmationModal, animated: true, completion: nil)
                return false
                
            case .notDetermined:
                AVCaptureDevice.requestAccess(for: .video, completionHandler: { _ in
                    onAuthorized?()
                })
                return false
                
            default: return false
        }
    }

    public static func requestMicrophonePermissionIfNeeded(
        presentingViewController: UIViewController? = nil,
        onNotGranted: (() -> Void)? = nil
    ) {
        switch AVAudioSession.sharedInstance().recordPermission {
            case .granted: break
            case .denied:
                guard let presentingViewController: UIViewController = (presentingViewController ?? CurrentAppContext().frontmostViewController()) else { return }
                onNotGranted?()
                
                let confirmationModal: ConfirmationModal = ConfirmationModal(
                    info: ConfirmationModal.Info(
                        title: "Session",
                        body: .text(
                            String(
                                format: "modal_permission_explanation".localized(),
                                "modal_permission_microphone".localized()
                            )
                        ),
                        confirmTitle: "modal_permission_settings_title".localized(),
                        dismissOnConfirm: false,
                        onConfirm: { [weak presentingViewController] _ in
                            presentingViewController?.dismiss(animated: true, completion: {
                                UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
                            })
                        },
                        afterClosed: { onNotGranted?() }
                    )
                )
                presentingViewController.present(confirmationModal, animated: true, completion: nil)
                
            case .undetermined:
                onNotGranted?()
                AVAudioSession.sharedInstance().requestRecordPermission { _ in }
                
            default: break
        }
    }

    public static func requestLibraryPermissionIfNeeded(
        presentingViewController: UIViewController? = nil,
        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
                
                PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in
                    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:
                guard let presentingViewController: UIViewController = (presentingViewController ?? CurrentAppContext().frontmostViewController()) else { return }
                
                let confirmationModal: ConfirmationModal = ConfirmationModal(
                    info: ConfirmationModal.Info(
                        title: "Session",
                        body: .text(
                            String(
                                format: "modal_permission_explanation".localized(),
                                "modal_permission_library".localized()
                            )
                        ),
                        confirmTitle: "modal_permission_settings_title".localized(),
                        dismissOnConfirm: false
                    ) { [weak presentingViewController] _ in
                        presentingViewController?.dismiss(animated: true, completion: {
                            UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
                        })
                    }
                )
                presentingViewController.present(confirmationModal, animated: true, completion: nil)
                
            default: return
        }
    }
}