//Created  on 2019/7/27 by  LCD:https://github.com/liucaide .

/***** 模块文档 *****
 *
 */




import Foundation
import CaamDau
import TZImagePickerController


public class TWImagePicker {
    public enum Style {
        /// 不裁剪
        case value1
        /// 裁剪 circle 是否圆形
        case value2(_ circle:Bool)
        /// 自定义裁剪尺寸裁剪
        case value3(_ r:CGRect)
    }
    public static var addImage:UIImage = Assets().com_addphoto
    public var maxPhotoCount = 4
    public var list:[Model]
    public var style:Style = .value1
    public var assets:[PHAsset]
    public var urls:[URL]
    public var images:[UIImage]
    public var isOriginalPhoto = false
    public var isSheet = false
    public init() {
        assets = []
        urls = []
        list = []
        images = [TWImagePicker.addImage]
    }
    
    public func showPhoto(_ index:Int, completion:(()->Void)? = nil) {
        guard index < images.count else{ return }
        if images[index] == TWImagePicker.addImage {
            if maxPhotoCount == 1 && isSheet {
                UIAlertController.cd_init(style: .actionSheet).cd
                    .action("取消", style: .cancel)
                    .action("拍照", handler: { [weak self](a) in
                        self?.takePhoto(completion)
                    })
                    .action("从相册中选择", handler: { [weak self](a) in
                        self?.choosePhoto(completion)
                    })
                    .show()
            }else{
                choosePhoto(completion)
            }
            
        }else{
            previewPhotoWithIndex(index)
        }
    }
    
    
    public func remove(_ index:Int) {
        guard index < images.count else{ return }
        guard index < assets.count else{ return }
        
        images.remove(at: index)
        assets.remove(at: index)
        list.remove(at: index)
        guard self.images.count < self.maxPhotoCount else {
            return
        }
        if let last = self.images.last, last == TWImagePicker.addImage {
            return
        }
        self.images.append(TWImagePicker.addImage)
    }
    
    func actionSheet() {
        
    }
    
    public func previewPhotoWithIndex(_ idx:Int) {
        let picker = TZImagePickerController(selectedAssets: NSMutableArray(array: assets), selectedPhotos: NSMutableArray(array: images), index: idx)
        CD.present(picker!)
    }
    
    
    
    lazy var imagePicker: SysImagePicker = {
        return SysImagePicker()
    }()
}

//MARK:--- TZImagePickerController ----------
extension TWImagePicker {
    public func takePhoto(_ completion:(()->Void)? = nil) {
        imagePicker.takePhoto({ [weak self](photos, assets) in
            guard let self = self else { return }
            self.images = photos
            self.assets = assets
            self.isOriginalPhoto = true
            var arr:[Model] = []
            for (i,item) in self.assets.enumerated() {
                let m = Model()
                m.image = self.images[i]
                m.asset = item
                arr.append(m)
            }
            self.list = arr.map({ (m) -> Model in
                let mm = self.list.filter{$0.asset == m.asset}.map{$0}.first
                if let mm = mm {
                    m.isupload = mm.isupload
                    m.uploadurl = mm.uploadurl
                    m.param = mm.param
                }
                return m
            })
            guard self.images.count < self.maxPhotoCount else {
                completion?()
                return
            }
            self.images.append(TWImagePicker.addImage)
            completion?()
        })
    }
    
    
    
    public func choosePhoto(_ completion:(()->Void)? = nil) {
        let picker = TZImagePickerController(maxImagesCount: maxPhotoCount, columnNumber: 4, delegate: nil, pushPhotoPickerVc: true)
        //个性化设置
        picker?.naviBgColor = UIColor.white
        picker?.naviTitleColor = Config.color.txt_1
        picker?.oKButtonTitleColorNormal = Config.color.main_1
        picker?.barItemTextColor = Config.color.txt_1
        //picker?.oKButtonTitleColorDisabled
        picker?.navigationBar.isTranslucent = true
        picker?.isSelectOriginalPhoto = false
        picker?.allowTakePicture = true
        switch style {
        case .value1:
            picker?.showSelectBtn = false
            picker?.allowCrop = false
            picker?.needCircleCrop = false
        case .value2(let circle):
            picker?.showSelectBtn = false
            picker?.allowCrop = true
            picker?.cropRect = CGRect(y:(CD.screenH-CD.screenW)/2, w: CD.screenW, h: CD.screenW)
            picker?.needCircleCrop = circle
        case .value3(let r):
            picker?.showSelectBtn = false
            picker?.allowCrop = true
            picker?.needCircleCrop = false
            picker?.cropRect = r
        }
        // 3. 设置是否可以选择视频/图片/原图
        picker?.allowPickingVideo = false
        picker?.allowPickingImage = true
        picker?.allowPickingOriginalPhoto = true
        picker?.allowPickingGif = false
        picker?.allowPickingMultipleVideo = false // 是否可以多选视频
        // 4. 照片排列按修改时间升序
        picker?.sortAscendingByModificationDate = true
        picker?.statusBarStyle = .default
        
        //picker?.photoOriginDefImage =  UIImage.cd_iconfont(CD_IconFont.tround(22), color: Config.color.txt_5)
        //picker?.photoOriginSelImage = UIImage.cd_iconfont(CD_IconFont.tround_check_fill(22), color: Config.color.main_1)
        //picker?.photoDefImage = UIImage.cd_iconfont(CD_IconFont.tround_check(22), color: Config.color.hex("f"))
        //picker?.photoSelImage = UIImage.cd_iconfont(CD_IconFont.tround_check_fill(22), color: Config.color.main_1)
        picker?.navLeftBarButtonSettingBlock = { btn in
            let img = UIImage.cd_iconfont(CD_IconFont.tback_light(22), color: Config.color.txt_1)
            btn?.cd
                .image(img)
                .clips(false)
                .contentAlignment(horizontal: .left)
                .image(UIEdgeInsets(t: 0, l: -5, b: 0, r: 0))
        }
        /// 回调
        //([UIImage]?, [Any]?, Bool)
        picker?.selectedAssets = NSMutableArray(array: assets)
        picker?.didFinishPickingPhotosWithInfosHandle = { (photos, assets, isSelectOriginalPhoto, infos) in
            
        }
        picker?.didFinishPickingPhotosHandle = { [weak self](photos, assets, isSelectOriginalPhoto) in
            guard let self = self else { return }
            self.images = photos ?? []
            self.assets = assets as? [PHAsset] ?? []
            self.isOriginalPhoto = isSelectOriginalPhoto
            var arr:[Model] = []
            for (i,item) in self.assets.enumerated() {
                let m = Model()
                m.image = self.images[i]
                m.asset = item
                arr.append(m)
            }
            self.list = arr.map({ (m) -> Model in
                let mm = self.list.filter{$0.asset == m.asset}.map{$0}.first
                if let mm = mm {
                    m.isupload = mm.isupload
                    m.uploadurl = mm.uploadurl
                    m.param = mm.param
                }
                return m
            })
            guard self.images.count < self.maxPhotoCount else {
                completion?()
                return
            }
            self.images.append(TWImagePicker.addImage)
            completion?()
        }
        CD.present(picker!, animated: false)
    }
}


extension TWImagePicker {
    public class Model {
        public init(){}
        open var asset:PHAsset? {
            didSet {
                guard let asset = asset else { return }
                PHImageManager.default().requestImage(for: asset, targetSize: PHImageManagerMaximumSize, contentMode: .default, options: nil, resultHandler: { (img, info) in
                    var path = info?.stringValue("PHImageFileURLKey") ?? ""
                    if path.hasPrefix("file://") {
                        path[0..<7] = ""
                    }
                    self.url = URL(fileURLWithPath: path)
                    
                })
            }
        }
        open var image:UIImage?
        open var url:URL?
        open var isupload:Bool = false
        open var uploadurl:String = ""
        open var param:[String:Any] = [:]
    }
}



class SysImagePicker: NSObject {
    var location: CLLocation?
    lazy var picker: UIImagePickerController = {
        let p = UIImagePickerController()
        p.delegate = self
        return p
    }()
    var callback:(([UIImage], [PHAsset])->Void)?
}
//MARK:--- UIImagePickerController ----------
extension SysImagePicker: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func takePhoto(_ callback:(([UIImage], [PHAsset])->Void)?) {
        let authStatus = AVCaptureDevice.authorizationStatus(for: .video)
        let s = PHPhotoLibrary.authorizationStatus()
        self.callback = callback
        
        func take(){
            switch authStatus {
            case .restricted, .denied:
                UIAlertController.cd_init(title: "无法使用相机", message: #"请在iPhone的""设置-隐私-相机""中允许访问相机和相册"#).cd
                .action("取消")
                .action("设置", handler: { (a) in
                    if #available(iOS 10.0, *) {
                        UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
                    } else {
                        UIApplication.shared.openURL(URL(string: UIApplication.openSettingsURLString)!)
                    }
                })
                .show()
            case .authorized where s == .denied:
                UIAlertController.cd_init(title: "无法访问相册", message: #"请在iPhone的""设置-隐私-相册""中允许访问相册和相机"#).cd
                .action("取消")
                .action("设置", handler: { (a) in
                    if #available(iOS 10.0, *) {
                        UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
                    } else {
                        UIApplication.shared.openURL(URL(string: UIApplication.openSettingsURLString)!)
                    }
                })
                .show()
            case .notDetermined:
                //防止用户首次拍照拒绝授权时相机页黑屏
                AVCaptureDevice.requestAccess(for: .video) { (b) in
                    if b {
                        DispatchQueue.main.async {
                            take()
                        }
                        
                    }
                }
            case .authorized where s == .notDetermined:
                TZImageManager.default()?.requestAuthorization(completion: {
                    take()
                })
            default:
                pushImagePickerController()
            }
        }
        
        take()
        
    }
    
    func pushImagePickerController() {
        /*
        TZLocationManager.default()?.startLocation(successBlock: { [weak self](l) in
            self?.location = l?.first
        }, failureBlock: { _ in
            
        })*/
        guard UIImagePickerController.isSourceTypeAvailable(.camera) else { return }
        picker.sourceType = .camera
        CD.present(picker)
    }
    
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        hud_loading(title: "正在处理")
        guard let type = info[UIImagePickerController.InfoKey.mediaType] as? String, type == "public.image" else {
            hud_hidden()
            hud_error("保存失败，请重试");
            return
        }
        guard let img = info[UIImagePickerController.InfoKey.originalImage] as? UIImage,
        let meta = info[UIImagePickerController.InfoKey.mediaMetadata] as? [AnyHashable : Any]
        else {
            hud_hidden()
            hud_error("保存失败，请重试");
            return
        }
        TZImageManager.default()?.savePhoto(with: img, meta: meta, location: location, completion: { [weak self](asset, error) in
            hud_hidden()
            guard error == nil else{
                hud_error("保存失败，请重试")
                return
            }
            guard let asset = asset else{return}
            TZImageManager.default()?.createModel(with: asset)
            self?.callback?([img], [asset])
            picker.dismiss(animated: true, completion: nil)
        })
        
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }
}
