//
//  YHMediaUploadSheetView.swift
//  galaxy
//
//  Created by alexzzw on 2025/9/27.
//  Copyright © 2025 https://www.galaxy-immi.com. All rights reserved.
//
/*
【Usage】
 
 YHMediaUploadSheetView.sheetView().show { [weak self] mediaItems in
    guard let self = self else { return }
    print("获得 \(mediaItems.count) 个媒体文件")
    // 处理选中的媒体文件
 }
*/

import UIKit
import Photos
import PhotosUI
import AVFoundation
import MobileCoreServices
import SnapKit

enum YHMediaUploadType: Int {
    case camera = 1      // 拍照/录像
    case photoLibrary = 2 // 相册选择
    case cancel = 3      // 取消
}

class YHMediaUploadItem {
    var type: YHMediaUploadType
    var title: String
    
    init(type: YHMediaUploadType, title: String) {
        self.type = type
        self.title = title
    }
}

class YHMediaUploadSheetView: UIView {
    
    // 决定最终媒体选择数量最大值
    var maxSelectCount: Int = 9
    
    var uploadTypeArr = [
        YHMediaUploadItem(type: .camera, title: "拍照"),
        YHMediaUploadItem(type: .photoLibrary, title: "从手机相册选择"),
        YHMediaUploadItem(type: .cancel, title: "取消")
    ]
    
    // 上传媒体回调
    var uploadMediaBlock: (([YHSelectMediaItem]) -> Void)?
    private var needSelectVideo = false
    
    lazy var blackMaskView: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor(hex: 0x0F1214, alpha: 0.5)
        let tap = UITapGestureRecognizer(target: self, action: #selector(dismiss))
        view.addGestureRecognizer(tap)
        return view
    }()
    
    lazy var whiteContentView: UIView = {
        let view = UIView()
        view.backgroundColor = .white
        return view
    }()
    
    lazy var tableView: UITableView = {
        let tableView = UITableView(frame: .zero, style: .grouped)
        if #available(iOS 11.0, *) {
            tableView.contentInsetAdjustmentBehavior = .never
        }
        tableView.showsVerticalScrollIndicator = false
        tableView.separatorStyle = .none
        tableView.delegate = self
        tableView.dataSource = self
        tableView.backgroundColor = .white
        tableView.isScrollEnabled = false
        tableView.register(YHMediaUploadTypeCell.self, forCellReuseIdentifier: YHMediaUploadTypeCell.cellReuseIdentifier)
        return tableView
    }()
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        createUI()
    }
    
    static func sheetView() -> YHMediaUploadSheetView {
        let view = YHMediaUploadSheetView(frame: UIScreen.main.bounds)
        return view
    }
    
    func createUI() {
        self.addSubview(blackMaskView)
        self.addSubview(whiteContentView)
        whiteContentView.addSubview(tableView)
        
        blackMaskView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        // 计算内容高度：2个section，第一个section 2行，第二个section 1行，加上section间距和安全区域
        let contentHeight = 54.0 * 3 + 8.0 + k_Height_safeAreaInsetsBottom()
        
        whiteContentView.snp.makeConstraints { make in
            make.left.right.bottom.equalToSuperview()
            make.height.equalTo(contentHeight)
        }
        
        tableView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }
}

extension YHMediaUploadSheetView {
    
    func show(needSelectVideo: Bool = false, completion: @escaping ([YHSelectMediaItem]) -> Void) {
        self.needSelectVideo = needSelectVideo
        self.uploadMediaBlock = completion
        UIApplication.shared.yhKeyWindow()?.addSubview(self)
    }
    
    @objc func dismiss() {
        self.removeFromSuperview()
    }
}

// MARK: - TableView DataSource & Delegate
extension YHMediaUploadSheetView: UITableViewDelegate, UITableViewDataSource {
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 0 {
            return 2 // 拍照 + 从手机相册选择
        } else {
            return 1 // 取消
        }
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: YHMediaUploadTypeCell.cellReuseIdentifier, for: indexPath) as? YHMediaUploadTypeCell else {
            return UITableViewCell()
        }
        
        var itemIndex = 0
        if indexPath.section == 0 {
            itemIndex = indexPath.row
        } else {
            itemIndex = 2 // 取消按钮
        }
        
        if itemIndex < uploadTypeArr.count {
            cell.item = uploadTypeArr[itemIndex]
            
            // 第一个section的第一行显示分割线
            if indexPath.section == 0 && indexPath.row == 0 {
                cell.showSeparator = true
            } else {
                cell.showSeparator = false
            }
        }
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        var itemIndex = 0
        if indexPath.section == 0 {
            itemIndex = indexPath.row
        } else {
            itemIndex = 2 // 取消按钮
        }
        
        if itemIndex < uploadTypeArr.count {
            let operationItem = uploadTypeArr[itemIndex]
            if operationItem.type == .cancel {
                dismiss()
            } else if operationItem.type == .photoLibrary {
                selectMediaFromPhotoLibrary()
            } else if operationItem.type == .camera {
                showCameraWithBothModes()
            }
        }
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 54.0
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return section == 0 ? 0.01 : 8.0
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 0.01
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        if section == 0 {
            let view = UIView()
            view.backgroundColor = nil
            return view
        } else {
            let view = UIView()
            view.backgroundColor = UIColor.brandGrayColor3
            return view
        }
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return UIView()
    }
}

// MARK: - Camera & Photo Library
extension YHMediaUploadSheetView {
    
    // 显示相机（拍照和录像在同一界面）
    func showCameraWithBothModes() {
        checkCameraPermission { [weak self] in
            self?.presentCameraWithBothModes()
        }
    }
    
    // 从相册选择
    func selectMediaFromPhotoLibrary() {
        checkPhotoLibraryPermission { [weak self] in
            self?.presentPhotoLibraryPicker()
        }
    }
    
    // 展示相机（同时支持拍照和录像）
    func presentCameraWithBothModes() {
        guard UIImagePickerController.isSourceTypeAvailable(.camera) else {
            YHHUD.flash(message: "设备不支持相机功能")
            return
        }
        
        let picker = UIImagePickerController()
        picker.delegate = self
        picker.sourceType = .camera
        
        // 同时支持拍照和录像
        var mediaTypes: [String] = []
        
        // 检查是否支持拍照和录像
        if let availableTypes = UIImagePickerController.availableMediaTypes(for: .camera) {
            if availableTypes.contains(kUTTypeImage as String) {
                mediaTypes.append(kUTTypeImage as String)
            }
            if needSelectVideo, availableTypes.contains(kUTTypeMovie as String) {
                mediaTypes.append(kUTTypeMovie as String)
            }
        }
        
        guard !mediaTypes.isEmpty else {
            YHHUD.flash(message: "设备不支持拍照或录像功能")
            return
        }
        
        picker.mediaTypes = mediaTypes
        
        // 设置视频录制参数
        picker.videoQuality = .typeMedium
        picker.videoMaximumDuration = 60.0 // 60秒
        
        // 默认是拍照模式，用户可以在界面中切换到录像
        picker.cameraCaptureMode = .photo
        
        picker.allowsEditing = true
        UIViewController.current?.present(picker, animated: true)
    }
    
    // 展示相册选择器
    func presentPhotoLibraryPicker() {
        if #available(iOS 14.0, *) {
            // iOS 14+ 使用 PHPickerViewController，支持多选
            var configuration = PHPickerConfiguration()
            configuration.selectionLimit = maxSelectCount
            // 同时支持图片和视频
            configuration.filter = needSelectVideo ? .any(of: [.images, .videos]) : .any(of: [.images])
            
            let picker = PHPickerViewController(configuration: configuration)
            picker.delegate = self
            UIViewController.current?.present(picker, animated: true)
        } else {
            // iOS 14以下使用 UIImagePickerController，只能单选
            if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
                let imagePicker = UIImagePickerController()
                imagePicker.delegate = self
                imagePicker.sourceType = .photoLibrary
                imagePicker.mediaTypes = needSelectVideo ? [kUTTypeImage as String, kUTTypeMovie as String] : [kUTTypeImage as String]
                UIViewController.current?.present(imagePicker, animated: true)
            }
        }
    }
}

// MARK: - 权限检查
extension YHMediaUploadSheetView {
    
    func checkCameraPermission(completion: @escaping () -> Void) {
        let cameraAuthStatus = AVCaptureDevice.authorizationStatus(for: .video)
        
        switch cameraAuthStatus {
        case .authorized:
            completion()
        case .notDetermined:
            AVCaptureDevice.requestAccess(for: .video) { granted in
                DispatchQueue.main.async {
                    if granted {
                        completion()
                    } else {
                        YHHUD.flash(message: "需要相机权限才能拍照")
                    }
                }
            }
        case .denied, .restricted:
            YHHUD.flash(message: "请在设置中打开相机权限")
        @unknown default:
            YHHUD.flash(message: "无法获取相机权限")
        }
    }
    
    func checkPhotoLibraryPermission(completion: @escaping () -> Void) {
        let photoAuthStatus = PHPhotoLibrary.authorizationStatus()
        
        switch photoAuthStatus {
        case .authorized, .limited:
            completion()
        case .notDetermined:
            PHPhotoLibrary.requestAuthorization { status in
                DispatchQueue.main.async {
                    if status == .authorized || status == .limited {
                        completion()
                    } else {
                        YHHUD.flash(message: "需要相册权限才能选择照片")
                    }
                }
            }
        case .denied, .restricted:
            YHHUD.flash(message: "请在设置中打开相册权限")
        @unknown default:
            YHHUD.flash(message: "无法获取相册权限")
        }
    }
}

// MARK: - UIImagePickerControllerDelegate
extension YHMediaUploadSheetView: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
        
        guard let mediaType = info[.mediaType] as? String else {
            picker.dismiss(animated: true)
            return
        }
        
        var mediaItems: [YHSelectMediaItem] = []
        
        if mediaType == kUTTypeImage as String {
            // 处理图片
            if let image = info[.originalImage] as? UIImage {
                var imageName = ""
                if let imageUrl = info[.imageURL] as? URL {
                    imageName = imageUrl.lastPathComponent
                }
                
                if imageName.isEmpty {
                    let timestamp = Date().timeIntervalSince1970
                    imageName = "\(timestamp).jpg".replacingOccurrences(of: ".", with: "")
                }
                
                let item = YHSelectMediaItem(name: imageName, type: .image, image: image)
                mediaItems.append(item)
            }
        } else if mediaType == kUTTypeMovie as String {
            // 处理视频
            if let videoURL = info[.mediaURL] as? URL {
                let videoName = videoURL.lastPathComponent
                let item = YHSelectMediaItem(name: videoName, type: .video, videoURL: videoURL)
                mediaItems.append(item)
            }
        }
        
        picker.dismiss(animated: true) {
            self.uploadMediaBlock?(mediaItems)
            self.dismiss()
        }
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true)
    }
}

// MARK: - PHPickerViewControllerDelegate
@available(iOS 14.0, *)
extension YHMediaUploadSheetView: PHPickerViewControllerDelegate {
    
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true)
        self.dismiss()
        if results.count <= 0 {
            return
        }
        
        let group = DispatchGroup()
        // 使用数组保持顺序，用可选类型处理失败情况
        var mediaItems: [YHSelectMediaItem?] = Array(repeating: nil, count: results.count)
        
        YHHUD.show(.progress(message: "处理中..."))
        
        for (index, result) in results.enumerated() {
            group.enter()
            
            // 检查是否是图片
            if result.itemProvider.hasItemConformingToTypeIdentifier(UTType.image.identifier) {
                result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.image.identifier) { url, _ in
                    defer { group.leave() }
                    
                    if let url = url, let imageData = try? Data(contentsOf: url), let image = UIImage(data: imageData) {
                        let imageName = url.lastPathComponent.isEmpty ? "\(Date().timeIntervalSince1970).jpg" : url.lastPathComponent
                        let item = YHSelectMediaItem(name: imageName, type: .image, image: image)
                        mediaItems[index] = item
                    }
                }
            }
            // 检查是否是视频
            else if result.itemProvider.hasItemConformingToTypeIdentifier(UTType.movie.identifier) {
                result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier) { url, error in
                    defer { group.leave() }
                    
                    if let url = url {
                        // 复制视频文件到临时目录
                        let tempURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(url.lastPathComponent)
                        do {
                            if FileManager.default.fileExists(atPath: tempURL.path) {
                                try FileManager.default.removeItem(at: tempURL)
                            }
                            try FileManager.default.copyItem(at: url, to: tempURL)
                            
                            let videoName = tempURL.lastPathComponent
                            let item = YHSelectMediaItem(name: videoName, type: .video, videoURL: tempURL)
                            mediaItems[index] = item
                        } catch {
                            printLog("视频文件复制失败: \(error)")
                            // 失败时 mediaItems[index] 保持为 nil
                        }
                    }
                }
            } else {
                // 不支持的类型，直接 leave
                group.leave()
            }
        }
        
        // 等待所有任务完成
        group.notify(queue: .main) {
            YHHUD.hide()
            // 过滤掉失败的项目，保持成功项目的相对顺序
            let successfulItems = mediaItems.compactMap { $0 }
            self.uploadMediaBlock?(successfulItems)
        }
    }
}

// MARK: - YHMediaUploadTypeCell
class YHMediaUploadTypeCell: UITableViewCell {
    
    static let cellReuseIdentifier = "YHMediaUploadTypeCell"
    
    var showSeparator: Bool = false {
        didSet {
            separatorView.isHidden = !showSeparator
        }
    }
    
    var item: YHMediaUploadItem? {
        didSet {
            guard let item = item else { return }
            titleLabel.text = item.title
            
            // 根据类型设置样式
            if item.type == .cancel {
                titleLabel.font = UIFont.PFSC_R(ofSize: 15)
            } else {
                titleLabel.font = UIFont.PFSC_M(ofSize: 15)
            }
        }
    }
    
    lazy var titleLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont.PFSC_M(ofSize: 15)
        label.textColor = UIColor.brandGrayColor8
        label.textAlignment = .center
        return label
    }()
    
    lazy var separatorView: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor.separator
        view.isHidden = true
        return view
    }()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setupUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func setupUI() {
        selectionStyle = .none
        backgroundColor = .white
        
        contentView.addSubview(titleLabel)
        contentView.addSubview(separatorView)
        
        titleLabel.snp.makeConstraints { make in
            make.center.equalToSuperview()
        }
        
        separatorView.snp.makeConstraints { make in
            make.left.equalToSuperview()
            make.right.equalToSuperview()
            make.bottom.equalToSuperview()
            make.height.equalTo(0.5)
        }
    }
}
