//
//  YHCertificateUploadSheetView.swift
//  galaxy
//
//  Created by edy on 2024/3/11.
//  Copyright © 2024 https://www.galaxy-immi.com. All rights reserved.
//
/*
【Usage】
 
 YHCertificateUploadSheetView.sheetView().show {
    [weak self] actionType in
    guard let self = self else { return }
    print("%d", actionType.rawValue)
 }

 */

import UIKit
import Photos
import PhotosUI

class YHSelectImageItem {
    var name: String
    var data: UIImage?
    
    init(name: String = "", data: UIImage? = nil) {
        self.name = name
        self.data = data
    }
}

enum YHCertificateUploadType: Int {
    
    case sample = 1
    case camera = 2
    case photo = 3
    case phoneFile = 4
    case wechatUpload = 5
    case cancel = 6
}

class YHCertificateUploadSheetView: UIView {
    
    // 决定最终图片选择数量最大值 赋值时先赋值 imageMaxCount 后赋值 maxSelectImageCount
    var imageMaxCount: Int = 9
    var tips = "支持的文件格式为jpg/jpeg、png、doc/docx、pptx、pdf，最多可上传99张图片或文件" {
        didSet {
            updateLayouts()
        }
    }
    
    // 外部根据业务在0~imageMaxCount之间变动
    var maxSelectImageCount = 9 {
        didSet {
            if maxSelectImageCount >= imageMaxCount {
                
            } else if  0 < maxSelectImageCount && maxSelectImageCount < imageMaxCount {
                imageMaxCount = maxSelectImageCount
                
            } else {
                imageMaxCount = 0
            }
        }
    }
    var uploadTypeArr = [
             YHCertificateUploadItem(type: .camera, title: "拍照上传"),
             YHCertificateUploadItem(type: .photo, title: "相册上传"),
             YHCertificateUploadItem(type: .phoneFile, title: "手机文件上传", subtitle: "从手机文件管理中上传"),
             YHCertificateUploadItem(type: .cancel, title: "取消")] {
        didSet {
            updateLayouts()
        }
    }

    // 上传文件
    var uploadFilesBlock: ((URL) -> Void)?
    // 上传图片
    var uploadImageBlock: (([YHSelectImageItem]) -> Void)?
    // 微信上传
    var wechatUploadBlock: (() -> Void)?
    
    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 topView: UIView = {
        let view = UIView()
        view.addSubview(titleLabel)
        view.addSubview(closeBtn)
        view.addSubview(lineView)
        
        titleLabel.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(16)
            make.left.right.equalToSuperview()
            make.height.equalTo(24)
        }
        closeBtn.snp.makeConstraints { make in
            make.centerY.equalTo(titleLabel)
            make.right.equalToSuperview().offset(-20)
            make.width.height.equalTo(24)
        }
        lineView.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(20)
            make.right.equalToSuperview().offset(-20)
            make.height.equalTo(1)
            make.top.equalTo(titleLabel.snp.bottom).offset(12)
            make.bottom.equalToSuperview()
        }
        return view
    }()
    
    lazy var titleLabel: UILabel = {
        let label = UILabel()
        label.textColor = UIColor.mainTextColor
        label.textAlignment = .center
        label.font = UIFont.PFSC_B(ofSize: 17)
        label.text = "请选择上传方式"
        return label
    }()
    
    lazy var lineView: UIView = {
        let label = UIView()
        label.backgroundColor = UIColor.separatorColor
        return label
    }()
    
    lazy var closeBtn: UIButton = {
        let btn = UIButton()
        btn.setImage(UIImage(named: "my_cer_sheet_close"), for: .normal)
        btn.addTarget(self, action: #selector(dismiss), for: .touchUpInside)
        return btn
    }()
    
    lazy var tableView: UITableView = {
        
        let tableView = UITableView(frame: .zero, style: .grouped)

        if #available(iOS 11.0, *) {
            tableView.contentInsetAdjustmentBehavior = .never
        }
        tableView.estimatedSectionHeaderHeight = 1.0
        tableView.estimatedSectionFooterHeight = 1.0
        tableView.showsVerticalScrollIndicator = false
        tableView.separatorStyle = .none
        tableView.delegate = self
        tableView.dataSource = self
        tableView.backgroundColor = .white
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "UITableViewCell")
        tableView.register(YHCertificateTemplateCell.self, forCellReuseIdentifier: YHCertificateTemplateCell.cellReuseIdentifier)
        tableView.register(YHCertificateUploadTypeCell.self, forCellReuseIdentifier: YHCertificateUploadTypeCell.cellReuseIdentifier)
        return tableView
    }()
    
    var fileTypes: [String] = [ "public.image",
                                "com.adobe.pdf",
                                "com.microsoft.word.doc",
                                "org.openxmlformats.wordprocessingml.document",
                                "com.microsoft.powerpoint.ppt",
                                "org.openxmlformats.presentationml.presentation"
    ]
    
    lazy var documentPickerVC: UIDocumentPickerViewController = {
        
         if #available(iOS 14.0, *) {
             var arr: [UTType] = []
             for fileType in self.fileTypes {
                 if let type = UTType(fileType) {
                     arr.append(type)
                 }
             }
             let docPickerVC = UIDocumentPickerViewController(forOpeningContentTypes: arr)
             docPickerVC.delegate = self
             return docPickerVC
         }
         let docPickerVC = UIDocumentPickerViewController(documentTypes: self.fileTypes, in: .open)
         docPickerVC.delegate = self
         return docPickerVC
    }()
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        createUI()
    }
    
    static func sheetView() -> YHCertificateUploadSheetView {
        let view = YHCertificateUploadSheetView(frame: UIScreen.main.bounds)
        return view
    }
    
    func createUI() {
        
        self.addSubview(blackMaskView)
        self.addSubview(whiteContentView)
        whiteContentView.addSubview(topView)
        whiteContentView.addSubview(tableView)

        let corner = UIRectCorner(rawValue: UIRectCorner.topLeft.rawValue | UIRectCorner.topRight.rawValue)
        let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corner, cornerRadii: CGSize(width: kCornerRadius6, height: kCornerRadius6))
        let layer = CAShapeLayer()
        layer.frame = whiteContentView.bounds
        layer.path = path.cgPath
        whiteContentView.layer.mask = layer
        
        blackMaskView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        
        let whiteHeight = calculateHeight()
        whiteContentView.snp.makeConstraints { make in
            make.left.right.bottom.equalToSuperview()
            make.height.equalTo(whiteHeight)
        }
        topView.snp.makeConstraints { make in
            make.top.left.right.equalToSuperview()
        }
        
        tableView.snp.makeConstraints { make in
            make.left.right.bottom.equalToSuperview()
            make.top.equalTo(topView.snp.bottom).offset(0)
        }
        
    }
    
    func updateLayouts() {
        let whiteHeight = calculateHeight()
        whiteContentView.snp.remakeConstraints { make in
            make.left.right.bottom.equalToSuperview()
            make.height.equalTo(whiteHeight)
        }
        topView.snp.remakeConstraints { make in
            make.top.left.right.equalToSuperview()
        }
        
        tableView.snp.remakeConstraints { make in
            make.left.right.bottom.equalToSuperview()
            make.top.equalTo(topView.snp.bottom).offset(0)
        }
        if tips == "" {
            lineView.isHidden = true
        }
        self.setNeedsLayout()
        self.layoutIfNeeded()
    }
    
    func calculateHeight() -> CGFloat {
    
        // 注意事项文字高度
        var descHeight = tips.boundingRect(with: CGSize(width: KScreenWidth-40.0, height: .greatestFiniteMagnitude),
                                           options: .usesLineFragmentOrigin,
                                           attributes: [.font: UIFont.PFSC_R(ofSize: 14)],
                                           context: nil).size.height

        descHeight = ceil(descHeight)+21+34
        // 底部5个操作行高度之和
        let actionsHeight = 52.0 * Double(uploadTypeArr.count)
        var tableViewHeight = descHeight+actionsHeight
        if tips == "" {
            tableViewHeight = actionsHeight
        }
        // 白色View总高度
        var totalHeight = 53.0+tableViewHeight+k_Height_safeAreaInsetsBottom()
        if totalHeight > KScreenHeight {
            totalHeight = 458
        }
        return totalHeight
    }
}

extension YHCertificateUploadSheetView {
    
    func show() {
        self.tableView.reloadData()
        UIApplication.shared.yhKeyWindow()?.addSubview(self)
    }
    
    @objc func dismiss() {
        self.removeFromSuperview()
    }
}

extension YHCertificateUploadSheetView: UITableViewDelegate, UITableViewDataSource {
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return uploadTypeArr.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        guard let cell = tableView.dequeueReusableCell(withIdentifier: YHCertificateUploadTypeCell.cellReuseIdentifier, for: indexPath) as? YHCertificateUploadTypeCell else {
            return UITableViewCell()
        }
        if 0 <= indexPath.row && indexPath.row < uploadTypeArr.count {
            cell.item = uploadTypeArr[indexPath.row]
        }
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            
            if 0 <= indexPath.row && indexPath.row < uploadTypeArr.count {
                let operationItem = uploadTypeArr[indexPath.row]
                if operationItem.type == .cancel {
                    dismiss()
                    
                } else if operationItem.type == .photo {
                    
                    selectPhoto()
                
                } else if operationItem.type == .camera {
                    takePhoto()
                
                } else if operationItem.type == .phoneFile {
                    selectFile()
                    
                } else if operationItem.type == .wechatUpload {
                    selectFileFromWeChatPragram()
                }
            }
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 52.0
    }
    
    private func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> CGFloat {
        return UITableView.automaticDimension
    }
    
    private func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> CGFloat {
        
        return 1.0
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        
        let view = UIView()
        let label = UILabel()
        label.textColor = UIColor.labelTextColor2
        label.textAlignment = .left
        label.font = UIFont.PFSC_R(ofSize: 14)
        label.numberOfLines = 0
        label.text = tips
        view.addSubview(label)
        if tips == "" {
        
        } else {
            label.snp.makeConstraints { make in
                make.top.equalToSuperview().offset(21)
                make.left.equalToSuperview().offset(20)
                make.right.equalToSuperview().offset(-20)
                make.bottom.equalToSuperview().offset(-21)
            }
        }
        return view
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return UIView()
    }
}

extension YHCertificateUploadSheetView: (UIImagePickerControllerDelegate & UINavigationControllerDelegate) {
    
    private func getPhotoLibraryAuthorization(notDeterminedBlock: (() -> Void)?) -> Bool? {
        let authorizationStatus = PHPhotoLibrary.authorizationStatus()
        switch authorizationStatus {
        case .authorized:
            print("已经授权")
            return true
        case .notDetermined:
            print("不确定是否授权")
            // 请求授权
            PHPhotoLibrary.requestAuthorization {
                _ in
                notDeterminedBlock?()
            }
            return nil
        case .denied:
            print("拒绝授权")
            case .restricted:
            print("限制授权")
        case .limited: break
        @unknown default:
            break
        }
        return false
    }
    
    private func getCaptureDeviceAuthorization(notDeterminedBlock: (() -> Void)?) -> Bool? {
        let cameraAuthStatus = AVCaptureDevice.authorizationStatus(for: .video)
        
        switch cameraAuthStatus {
        case .authorized:
            // 已授权，直接使用相机
           return true
            
        case .notDetermined:
            // 未请求过权限，主动请求
            AVCaptureDevice.requestAccess(for: .video) { _ in
                notDeterminedBlock?()
            }
            return nil
        case .denied, .restricted:
            // 权限被拒绝或受限
            break
        @unknown default:
            break
        }
        return false
    }
    
     func takePhoto() {
         guard let authorization = getCaptureDeviceAuthorization(notDeterminedBlock: {
             DispatchQueue.main.async {
                 self.takePhoto()
             }
         }) else {
             return
         }
         
         if !authorization {
             YHHUD.flash(message: "请在设置中打开相机权限")
             return
         }
             
         if UIImagePickerController.isSourceTypeAvailable(.camera) {
            // 创建图片控制器
            let imagePicker = UIImagePickerController()
            // 设置代理
            imagePicker.delegate = self
            // 设置来源
            imagePicker.sourceType = .camera
            // 打开相机
            UIViewController.current?.present(imagePicker, animated: true, completion: { () in
                 
            })
        } else {
            printLog("找不到相机")
        }
    }
    
    func selectPhoto() {
        guard let authorization = getPhotoLibraryAuthorization(notDeterminedBlock: {
            DispatchQueue.main.async {
                self.selectPhoto()
            }
            
        }) else {
            return
        }
        
        if !authorization {
            YHHUD.flash(message: "请在设置中打开相册权限")
            return
        }
        
         if #available(iOS 14.0, *) { // iOS14以上可多选
                    
            var configuration = PHPickerConfiguration()
            // 设置最大选择数量
            configuration.selectionLimit = imageMaxCount
            // 设置选择器的过滤条件 只显示图片
            configuration.filter = .images
            let picker = PHPickerViewController(configuration: configuration)
            picker.delegate = self
            UIViewController.current?.present(picker, animated: true, completion: nil)
             
         } else { // iOS14以下只能单选
             
             if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
                 let imagePicker = UIImagePickerController()
                 imagePicker.delegate = self
                 imagePicker.sourceType = .photoLibrary
                 // 这一句，开始调用图库
                 UIViewController.current?.present(imagePicker, animated: true)
             }
         }
    }
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
        
        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
        
            var imageName = ""
            // 获取照片的名称
            if let imageUrl = info[.imageURL] as? URL {
                let lastComponent = imageUrl.lastPathComponent
                imageName = lastComponent
            }
            
            if imageName.isEmpty {
                let timestamp = Date().timeIntervalSince1970
                var timestampString = "\(timestamp)".replacingOccurrences(of: ".", with: "")
                imageName = "\(timestampString).jpg"
            }
            
            let item = YHSelectImageItem(name: imageName, data: image)
            uploadImageBlock?([item])
            self.dismiss()

        } else {
            printLog("pick image wrong")
            self.dismiss()
        }
        // 收回图库选择界面
        picker.dismiss(animated: true, completion: nil)
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }
}

extension YHCertificateUploadSheetView: PHPickerViewControllerDelegate {
    
    func getImageFromURL(url: URL) -> UIImage? {
        if let imageData = try? Data(contentsOf: url) {
            return UIImage(data: imageData)
        }
        return nil
    }
    
    @available(iOS 14.0, *)
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true, completion: nil)
        
        self.dismiss()
        if results.count <= 0 { // 取消的时候会调用到此处
            return
        }
        
        let group = DispatchGroup()
        var imageArr: [YHSelectImageItem] = []

        YHHUD.show(.progress(message: "上传中..."))
        for result in results {
            group.enter()
            // 此方法是异步操作
            result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.image.identifier) { url, error in
                if let error = error {
                    print("Error loading image: \(error.localizedDescription)")
                    
                } else if let url = url {
                    print(url)
                    if let image = self.getImageFromURL(url: url) {
                        var imgName = url.lastPathComponent
                        if imgName.isEmpty {
                            let timestamp = Date().timeIntervalSince1970
                            imgName = "\(timestamp).jpg"
                        }
                        let item = YHSelectImageItem(name: imgName, data: image)
                        imageArr.append(item)
                    }
                }
                group.leave()
            }
        }
        
        // 等待所有任务完成
        group.notify(queue: .main) {
            // 所有任务完成，回到主线程继续执行
            YHHUD.hide()
            print("所有任务完成")
            self.uploadImageBlock?(imageArr)
        }
    }
}

extension YHCertificateUploadSheetView: UIDocumentPickerDelegate {
    
    func selectFile() {
        YHOSSManager.share.getOSSID()
        UIViewController.current?.present(documentPickerVC, animated: true, completion: nil)
    }
    
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        guard let url = urls.first, let fileName = url.lastPathComponent.removingPercentEncoding else {
        
            return
        }
        print("\(url)")
        // 读取文件数据
        // 获取授权
        let fileUrlAuthozied = url.startAccessingSecurityScopedResource()
        if fileUrlAuthozied {
            // 通过文件协调工具来得到新的文件地址，以此得到文件保护功能
            let fileCoordinator = NSFileCoordinator()
            var error: NSError?
            fileCoordinator.coordinate(readingItemAt: url, options: [.forUploading], error: &error) {
                fileUrl in
                
                dismiss()
                uploadFilesBlock?(fileUrl)
                
            }
            url.stopAccessingSecurityScopedResource()
            if let error = error {
                printLog("\(error.localizedDescription)")
            }
        } else {
            YHHUD.flash(message: "文件授权失败")
            dismiss()
        }
    }
    
    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
        
    }
}

extension YHCertificateUploadSheetView {
    
    func selectFileFromWeChatPragram() {
        self.wechatUploadBlock?()
        dismiss()
    }
}
