//
//  LNMediaPicker.swift
//  Lanu
//
//  Created by OneeChan on 2025/11/26.
//

import Foundation
import UIKit
import Photos


enum LNMediaPickerType: CaseIterable {
    case camera
    case photo
    
    var title: String {
        switch self {
        case .camera: .init(key: "A00011")
        case .photo: .init(key: "A00012")
        }
    }
}


extension LNBottomSheetMenu {
    static func showImageSelectMenu(view: UIView? = nil,
                                    options: LNMediaPickerOptions = .init(),
                                    handler: @escaping LNMediaPickerHandler) {
        let panel = LNBottomSheetMenu()
        let types: [LNMediaPickerType] = [.camera, .photo]
        panel.update([
            LNMediaPickerType.camera.title,
            LNMediaPickerType.photo.title,
            .init(key: "A00003")
        ]) { index, _ in
            guard index < types.count else { return }
            let type = types[index]
            LNMediaPicker.shared.pick(from: view, type: type, options: options, handler: handler)
        }
        panel.popup()
    }
}


extension LNCommonAlertView {
    static func showPhotoLibraryPermissionAlert() {
        let alert = LNCommonAlertView()
        alert.titleLabel.text = .init(key: "A00287")
        alert.showConfirm(.init(key: "A00289")) {
            openAppSetting()
        }
        alert.showCancel()
        alert.popup()
    }
    
    static func showCameraPermissionAlert() {
        let alert = LNCommonAlertView()
        alert.titleLabel.text = .init(key: "A00288")
        alert.showConfirm(.init(key: "A00289")) {
            openAppSetting()
        }
        alert.showCancel()
        alert.popup()
    }
}


typealias LNMediaPickerHandler = (_ image: UIImage?, _ videoUrl: URL?) -> Void

struct LNMediaPickerOptions {
    let allowEdit: Bool
    let allowVideo: Bool
    let videoMaximumDuration: TimeInterval

    init(allowEdit: Bool = false,
         allowVideo: Bool = false,
         videoMaximumDuration: TimeInterval = 60) {
        self.allowEdit = allowEdit
        self.allowVideo = allowVideo
        self.videoMaximumDuration = videoMaximumDuration
    }
}

private var mediaHandlerKey: UInt8 = 0
extension UIViewController {
    fileprivate var mediaPickerHandler: LNMediaPickerHandler? {
        get {
            objc_getAssociatedObject(self, &mediaHandlerKey) as? LNMediaPickerHandler ?? nil
        }
        set {
            objc_setAssociatedObject(self, &mediaHandlerKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
}

class LNMediaPicker: NSObject {
    static let shared = LNMediaPicker()
    
    private override init() {
        super.init()
    }
}

extension LNMediaPicker {
    func pick(from view: UIView? = nil,
              type: LNMediaPickerType,
              options: LNMediaPickerOptions,
              handler: @escaping LNMediaPickerHandler) {
        switch type {
        case .photo:
            handlePhotoAuthorization(view: view, options: options, handler: handler)
        case .camera:
            handleCameraAuthorization(view: view, options: options, handler: handler)
        }
    }

    private func handlePhotoAuthorization(view: UIView?,
                                          options: LNMediaPickerOptions,
                                          handler: @escaping LNMediaPickerHandler) {
        // 申请相册权限（iOS 10+ 需授权）
        LNPermissionHelper.requestPhotoLibraryAuthorization { [weak self] status in
            guard let self else { return }
            switch status {
            case .authorized: // 已授权，打开相册
                self.presentPicker(from: view, sourceType: .photoLibrary, options: options, handler: handler)
            case .denied, .restricted: // 拒绝授权或受限制
                LNCommonAlertView.showPhotoLibraryPermissionAlert()
                handler(nil, nil)
            case .notDetermined: // 首次请求，系统会自动弹出授权框（无需额外处理）
                break
            case .limited:
                break
            @unknown default:
                break
            }
        }
    }

    private func handleCameraAuthorization(view: UIView?,
                                           options: LNMediaPickerOptions,
                                           handler: @escaping LNMediaPickerHandler) {
        let status = LNPermissionHelper.cameraAuthorizationStatus()

        switch status {
        case .authorized: // 已授权
            presentPicker(from: view, sourceType: .camera, options: options, handler: handler)
        case .notDetermined: // 未决定，请求权限
            LNPermissionHelper.requestCameraAccess { [weak self] granted in
                guard let self else { return }
                guard granted else {
                    handler(nil, nil)
                    return
                }
                self.presentPicker(from: view, sourceType: .camera, options: options, handler: handler)
            }
        case .denied, .restricted: // 拒绝/受限
            LNCommonAlertView.showCameraPermissionAlert()
            handler(nil, nil)
        @unknown default:
            handler(nil, nil)
        }
    }
}

extension LNMediaPicker {
    private func presentPicker(from view: UIView?,
                               sourceType: UIImagePickerController.SourceType,
                               options: LNMediaPickerOptions,
                               handler: @escaping LNMediaPickerHandler) {
        let vc = view?.viewController ?? UIView.appKeyWindow?.rootViewController
        let picker = UIImagePickerController()
        picker.delegate = self
        picker.sourceType = sourceType
        picker.allowsEditing = options.allowEdit
        picker.mediaTypes = options.allowVideo
        ? [UTType.image.identifier, UTType.movie.identifier]
        : [UTType.image.identifier]
        if sourceType == .camera {
            picker.videoMaximumDuration = options.videoMaximumDuration
        }
        picker.mediaPickerHandler = handler
        vc?.present(picker, animated: true)
    }
}

extension LNMediaPicker: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        // 关闭相册
        picker.dismiss(animated: true)
        
        if let videoURL = info[.mediaURL] as? URL {
            picker.mediaPickerHandler?(nil, videoURL)
            return
        }
        
        // 获取选择的图片（editedImage：编辑后的图片，originalImage：原始图片）
        let image: UIImage?
        if let editedImage = info[.editedImage] as? UIImage {
            image = editedImage
        } else if let originalImage = info[.originalImage] as? UIImage {
            image = originalImage
        } else {
            image = nil
        }
        picker.mediaPickerHandler?(image, nil)
    }
    
    // 取消选择
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true)
        picker.mediaPickerHandler?(nil, nil)
    }
}


