//
//  PhotoRemoveViewController.swift
//  PhoneManager
//
//  Created by edy on 2025/5/13.
//

import UIKit
import SnapKit
import Photos

enum SlideDirection {
    case left
    case right
}

class PhotoRemoveViewController: BaseViewController {
    
    var mediaType : TrashTypeEnum? {
        didSet{
            if mediaType == .video {
                self.trashSubView.tipLabel.text = "The video in the trash can"
            }else {
                self.trashSubView.tipLabel.text = "The photo in the trash can"
            }
        }
    }
    
    var isHints:Bool{
        set {
            UserDefaults.standard.set(newValue, forKey: "swipIsShowKey")
            UserDefaults.standard.synchronize()
        }
        get{
            return UserDefaults.standard.object(forKey: "swipIsShowKey") as? Bool ?? false
        }
    }
    
    private var bottomConstraint: Constraint?
    
    let formatter = DateFormatter()
    
    lazy var navView : PhotoVideoDetailNavView = {
        let view = PhotoVideoDetailNavView()
        return view
    }()
    
    // MARK: - 属性
    private var photoViews: [PhotosRemoveBaseView] = []
    private var currentIndex : Int
    private var dataModel: [AssetModel]
    
    // 配置参数
    private let rotationStrength: CGFloat = 320
    private let rotationMax: CGFloat = .pi/4
    private let scaleStrength: CGFloat = -0.5
    private let scaleMax: CGFloat = 0.7
    private let actionMargin: CGFloat = 120
    
   // 创建两个按钮
    private lazy var trashButton = {
        let height:CGFloat = self.mediaType == .video ? 0 : 47/2.0
        
        let button = UIButton(frame: CGRect(x: self.view.centerX - 22 - 47, y: self.view.centerY + 509 * RScreenH() / 2 - height , width: 47, height: 47))
        button.setImage(UIImage(named: "Group_1171275243"), for: .normal)
        button.setImage(UIImage(named: "Group_1171275242"), for: .selected)
        button.addTarget(self, action: #selector(trashButtonAction), for: .touchUpInside)
        return button
    }()
    private lazy var keepListButton = {
        let height:CGFloat = self.mediaType == .video ? 0 : 47/2.0
        let button = UIButton(frame: CGRect(x: self.view.centerX + 22, y: self.view.centerY + 509 * RScreenH() / 2 - height, width: 47, height: 47))
        button.setImage(UIImage(named: "Group_1171275102 3"), for: .normal)
        button.setImage(UIImage(named: "Group_1171275102 2"), for: .selected)
        button.addTarget(self, action: #selector(keepListButtonAction), for: .touchUpInside)
        return button
    }()
    
    
    
    lazy var trashSubView : TrashSubView = {
        let view = TrashSubView()
        view.backgroundColor = UIColor.colorWithHex(hexStr: "#F2F6FC")
        view.isHidden = true
        return view
    }()
    
    
    // MARK: - 初始化
    init(data: [AssetModel],currentIndex:Int,mediaType:TrashTypeEnum) {
        self.mediaType = mediaType
        let tempData = data
        // 从currentIndex截断拼接在末尾，设置currentIndex为0，将单利的数据拼接在最前面
        var tempArray : [AssetModel] = []
        if let type = self.mediaType{
            if let dataSg = Singleton.shared.trashData[type]{
                tempArray = dataSg
            }
        }
        
        let result = tempArray + Array(tempData[currentIndex...]) + Array(tempData[..<currentIndex])
        self.currentIndex = tempArray.count
        self.dataModel = result
        super.init(nibName: nil, bundle: nil)
        
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    // MARK: - 按钮事件
    @objc func trashButtonAction(){
        if self.photoViews.count > 0 {
            if let view = self.photoViews.first {
                self.animateViewExit(view: view,direction: .left)
            }
           
        }
    }
    @objc func keepListButtonAction(){
        if self.photoViews.count > 0 {
            if let view = self.photoViews.first {
                self.animateViewExit(view: view,direction: .right)
            }
        }
    }
    

    func animateViewExit(view : PhotosRemoveBaseView, direction : SlideDirection) {
        // 1. 设置锚点
        let customAnchor = CGPoint(x: 0.5, y: 2.0)
        view.layer.anchorPoint = customAnchor
        
        // 2. 修正位置
        let originalCenter = view.center
        let offsetY = view.bounds.height * (customAnchor.y - 0.5)
        view.layer.position = CGPoint(
            x: originalCenter.x,
            y: originalCenter.y + offsetY
        )
        
        // 3. 执行动画
        UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseIn, animations: {
            view.transform = CGAffineTransform(rotationAngle: direction == SlideDirection.left ?  -.pi/6 : .pi/6)
            view.alpha = 0
        }) { _ in
            // 数据变化
            if direction == SlideDirection.left{
                // 删除操作,先存到单利
                self.vibrate()
                self.saveDataToDBAndSigtonTrash()
            }else {
                // 清除单利数据
                self.clearSigtonTrashData()
                // 保留操作
                self.vibrate()
                self.saveDataToSigtonKeepList()
            }
            // 视图变化
            self.recycleView()
        }
    }
    
    // MARK: - 生命周期
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.view.backgroundColor = .white//UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
        
        formatter.dateStyle = .medium
        formatter.timeStyle = .none
        if let type = self.mediaType {
            self.navView.showType = type == .video ? .dateAndSizeNav : .dateTimeNav
        }
        self.view.addSubview(self.navView)
        self.navView.snp.makeConstraints { make in
            make.top.left.right.equalToSuperview()
            make.height.equalTo(statusBarHeight + 44)
        }
        
        setupViews()
        self.view.addSubview(self.trashSubView)
        self.trashSubView.type = self.mediaType
        self.trashSubView.snp.makeConstraints { make in
            make.left.right.equalToSuperview()
            self.bottomConstraint = make.bottom.equalToSuperview().offset(78 + safeHeight).constraint
            make.height.equalTo(78 + safeHeight)
        }
       
        
        self.trashSubView.clearTashDataCallBack = {[weak self] in
            guard let self else {return}
            DispatchQueue.main.async {
                self.showCurrentPageUIWhenTashDataChanged()
                self.navigationController?.popViewController(animated: true)
            }
           
        }
        self.trashSubView.presentTashDetailViewClickCallBack = {[weak self] in
            guard let self else {return}
            // 进入垃圾桶详情页面
            DispatchQueue.main.async {
                let vc : TrashViewController = TrashViewController()
                vc.currentPage = self.getJumpPageIndex()
                vc.dissmisCallBack = {[weak self] in
                    guard let self else {return}
                    self.showCurrentPageUIWhenTashDataChanged()
                }
                self.present(vc, animated: true)
            }
        }
        
        self.navView.reSetCallBack = {
            // 拿到单利中最后一个
            if  let model = self.getSigtonCurrentMediaTrashLastData(){
                // 判断当前数组中有没有这个数据(有的话表示是在当前页面撤销)
                if self.dataModel.map({$0.localIdentifier}).contains(model.localIdentifier){
                    if self.currentIndex > 0 {
                        self.currentIndex = self.currentIndex - 1
                    }
                }else{
                    // 没有这个数据表示从外部跳转进这个页面，当前位置插入一个数据
                    self.dataModel.insert(model, at: self.currentIndex)
                }
                // 重新设置下图片
                self.updateViewContents()
                // 视图层级处理
                self.bringCurrentViewToFront()
                // 移除当前数据
                self.removeCurrentMediaTypeTrashLastData()
                
                // 移除完成后 重新设置下按钮状态
                self.showCurrentPageUIWhenTashDataChanged()
            }
        }
        
        showCurrentPageUIWhenTashDataChanged()
        
        self.addListener()
        
        
        self.view.addSubview(self.trashButton)
        self.view.addSubview(self.keepListButton)
        
        if isHints == false {
            isHints = true
            self.view.addSubview(PMSwipHintView.xib())
        }
        
    }
    
    // 拿到当前类型垃圾桶数据的最后一个
    func getSigtonCurrentMediaTrashLastData() -> AssetModel? {
        var model : AssetModel?
        if let type = self.mediaType{
            if let dataSg = Singleton.shared.trashData[type]{
                let tempArray = dataSg
                if tempArray.count > 0 {
                    model = tempArray[tempArray.count - 1]
                }
            }
        }
        return model
    }
    
    // 跳转垃圾桶第几个page
    func getJumpPageIndex()->Int{
        if self.mediaType == .video {
            return 1
        }
        if self.mediaType == .other {
            return 2
        }
        if self.mediaType == .shot{
            return 3
        }
        return 1
    }
    
    private func addListener(){
        NotificationCenter.default.addObserver(forName: TrashDefaultView.jumpToPhotosDetailPageName, object: nil, queue: .main) {  [weak self] notification in
            guard let self = self,
            let type = notification.userInfo?["type"] as? String else { return }
            if let targetVC = self.navigationController?.viewControllers.first(where: { $0 is HomeViewController }) as? HomeViewController {
                self.navigationController?.popToViewController(targetVC, animated: false)
                let vc:HomePhotosDetailViewController = HomePhotosDetailViewController(mediaType: type == "Other" ? PhotsFileType.Other : PhotsFileType.screenshots)
                targetVC.navigationController?.pushViewController(vc, animated: true)
            }
        }
        NotificationCenter.default.addObserver(forName: TrashDefaultView.jumpToVideosDetailPageName, object: nil, queue: .main) { [weak self] notification in
            guard let self else {return}
            if let targetVC = self.navigationController?.viewControllers.first(where: { $0 is HomeViewController }) as? HomeViewController {
                self.navigationController?.popToViewController(targetVC, animated: false)
                let vc:HomeVideoDetailController = HomeVideoDetailController()
                targetVC.navigationController?.pushViewController(vc, animated: true)
            }
        }
    }
    private func removeCurrentMediaTypeTrashLastData() {
        // 移除单利中当前类型最后一个数据
        if let type = self.mediaType{
            if let dataSg = Singleton.shared.trashData[type]{
                var tempArray = dataSg
                if tempArray.count > 0 {
                    // 获取最后一个
                    let identifier = tempArray[tempArray.count - 1].localIdentifier
                    let success = TrashDatabase.shared.delete(localIdentifier: identifier)
                    if !success {
                        Print("删除失败")
                    }
                    tempArray.removeLast()
                }
                Singleton.shared.trashData[type] = tempArray
            }
        }
    }
    
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        // 视图消失的时候存到数据库
        saveDataToKeepListDB()
    }
    
    
    func changeDateToString() -> String{
        let model = self.dataModel[self.currentIndex]
        return formatter.string(from: model.createDate)
    }
    
    func chengeSizeToString()-> String {
        let model = self.dataModel[self.currentIndex]
        return formatFileSize(model.assetSize)
    }
    
    func showTrashView(){
        DispatchQueue.main.async {
            self.trashSubView.isHidden = false
            UIView.animate(withDuration: 0.2) {
                // 更新约束
                self.bottomConstraint?.update(offset: 0)
                self.view.layoutIfNeeded()
            }
        }
    }
    func hideTrashView(){
        DispatchQueue.main.async {
            UIView.animate(withDuration: 0.2) {
                // 更新约束
                self.bottomConstraint?.update(offset: 78 + safeHeight)
                self.view.layoutIfNeeded()
            }completion: { finished in
                self.trashSubView.isHidden = true
            }
        }
    }
    
    func showCurrentPageUIWhenTashDataChanged(){
        if let type  = self.mediaType{
            // 从数据库拿数据
            let dataDB = TrashDatabase.shared.queryByMediaType(type.dbType)
            var assetModel : [AssetModel] = []
            for item in dataDB {
                assetModel.append(AssetModel.init(localIdentifier: item.localIdentifier, assetSize: item.assetSize, createDate: item.createDate, mediaType: item.mediaType))
            }
            // 从单利拿数据
            DispatchQueue.main.async {
                if let type = self.mediaType{
                    if let dataSg = Singleton.shared.trashData[type]{
                        // 如果单利中有当前数据，显示撤回按钮
                        if dataSg.count > 0{
                            self.navView.resetButton.isHidden = false
                        }else{
                            self.navView.resetButton.isHidden = true
                        }
                        
                    }else {
                        self.navView.resetButton.isHidden = true
                    }
                }
            }
            if assetModel.count > 0 {
                // 显示垃圾桶
                self.trashSubView.resourceCountlabel.text = String(assetModel.count)
                self.showTrashView()
            }else{
                self.hideTrashView()
            }
        }
    }
    
    // MARK: - 视图设置
    private func setupViews() {
        // 只创建两个视图
        for _ in 0..<2 {
            let photoView = PhotosRemoveBaseView()
            photoView.mediaType = self.mediaType
            photoView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan)))
            self.view.addSubview(photoView)
            photoView.frame = CGRectMake(0, 0, self.view.width - 30, 509 * RScreenH())
            photoView.center = self.view.center
            photoView.innerVideoController?.player?.isMuted = true
            photoView.innerVideoController?.player?.volume = 0
            photoViews.append(photoView)
        }
        
        // 加载初始图片
        updateViewContents()
        bringCurrentViewToFront()
    }
    
    // 存垃圾桶数据到单利
    func saveDataToDBAndSigtonTrash(){
        // 拿到单利数据
        let model = self.dataModel[currentIndex]
        if let type = self.mediaType{
            if let dataSg = Singleton.shared.trashData[type]{
                var tempArray = dataSg
                tempArray.append(model)
                Singleton.shared.trashData[type] = tempArray
            }else{
                Singleton.shared.trashData[type] = [self.dataModel[currentIndex]]
            }
            // 保存当前数据到数据库
            let success = TrashDatabase.shared.insert(localIdentifier: model.localIdentifier, assetSize: model.assetSize, createDate: model.createDate, mediaType: type.dbType)
            if !success {
                Print("保存数据失败")
            }
        }
        self.showCurrentPageUIWhenTashDataChanged()
    }
    
    // 存保留数据到单利
    func saveDataToSigtonKeepList(){
        // 拿到单利数据
        if let type = self.mediaType{
            if let dataSg = Singleton.shared.keepList[type]{
                var tempArray = dataSg
                tempArray.append(self.dataModel[currentIndex])
                Singleton.shared.keepList[type] = tempArray
            }else{
                Singleton.shared.keepList[type] = [self.dataModel[currentIndex]]
            }
        }
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.31) {
            if PMKeepListAlert.isHint == false {
                PMKeepListAlert.isHint = true
                let alert = PMKeepListAlert()
                self.view.showBlur()
                alert.show {
                    self.view.hideBlur()
                }
            }
        }
    }
    
    func clearSigtonTrashData(){
        if let type = self.mediaType{
            Singleton.shared.trashData[type] = []
        }
        showCurrentPageUIWhenTashDataChanged()
    }
    
    /// 将保留列表单利数据存到数据库
    func saveDataToKeepListDB(){
        if let type = self.mediaType{
            if let dataSg = Singleton.shared.keepList[type]{
                var uinqueId = UUID().uuidString
                for item in dataSg{
                    if type == .video {
                        // 如果是视频的话不会进行分组，所以每次传入不同的id
                        // 重新生成一个
                        uinqueId = UUID().uuidString
                    }
                    let success = GroupDatabase.shared.insert(localIdentifier: item.localIdentifier, assetSize: item.assetSize, createDate: item.createDate, mediaType:  type == TrashTypeEnum.video ? 2 : 1,groupId: uinqueId)
                    if success == false {
                        Print("保留单利数据到数据库保留列表失败")
                    }
                }
                Singleton.shared.keepList[type] = []
            }
        }
    }
    
    // MARK: - 手势处理
    @objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
        guard let activeView = gesture.view as? PhotosRemoveBaseView else { return }
        
        // 记录初始位置
        let initialCenter = activeView.center
        let translation = gesture.translation(in: view)
        let velocity = gesture.velocity(in: view)
        
        switch gesture.state {
        case .began:
            activeView.initialCenter = initialCenter
            
        case .changed:
            // 使用增量位移更新位置
            activeView.center = CGPoint(
                x: activeView.initialCenter.x + translation.x,
                y: activeView.initialCenter.y + translation.y
            )
            
            updateActionButton(for: activeView, translation: translation)
            
        case .ended, .cancelled:
            // 计算实际位移（基于最终位置）
            let actualTranslation = CGPoint(
                x: activeView.center.x - activeView.initialCenter.x,
                y: activeView.center.y - activeView.initialCenter.y
            )
            
            // 使用实际位移判断
            if abs(actualTranslation.x) > actionMargin || abs(velocity.x) > 500 {
                removeCurrentView(translation: actualTranslation, velocity: velocity)
                if actualTranslation.x > 0 {
                    // 清除单利数据
                    clearSigtonTrashData()
                    // 保留操作
                    self.vibrate()
                    saveDataToSigtonKeepList()
                }
                if actualTranslation.x < 0 {
                    // 删除操作,先存到单利
                    self.vibrate()
                    saveDataToDBAndSigtonTrash()

                }
            } else {
                resetViewPosition(activeView)
            }
            gesture.setTranslation(.zero, in: view)
            
        default: break
        }
    }
    
    // MARK: - 视图更新逻辑
    private func updateViewContents() {
        for (index, view) in photoViews.enumerated() {
            let imageIndex = (currentIndex + index) % dataModel.count
            if self.mediaType == .video{
                self.getVideoURLFromLocalIdentifier(localIdentifier: dataModel[imageIndex].localIdentifier) { url, error in
                    if url != nil {
                        view.url = url
                        view.reload(index: index)
                    }
                }
            }else {
                PhotoManager.shared.asynGetImageFromAssetID(id: dataModel[imageIndex].localIdentifier) { image in
                    view.configure(with: image)
                }
            }
            
        }
        // 设置顶部title
        self.navView.titleLbel.text = changeDateToString()
        self.navView.sizeLbel.text = chengeSizeToString()
    }
    
    private func updateActionButton(for view: PhotosRemoveBaseView, translation: CGPoint) {
        if translation.x > 0 {
            self.trashButton.isSelected = false
            self.keepListButton.isSelected = true
            view.showRightButton()
        } else if translation.x < 0 {
            self.trashButton.isSelected = true
            self.keepListButton.isSelected = false
            view.showLeftButton()
        } else {
            self.keepListButton.isSelected = false
            self.trashButton.isSelected = false
            view.hideButtons()
        }
    }
    
    private func removeCurrentView(translation: CGPoint, velocity: CGPoint) {
        guard let activeView = photoViews.first else { return }
        
        let direction: CGFloat = translation.x > 0 ? 1 : -1
        let screenWidth = UIScreen.main.bounds.width
        
        UIView.animate(withDuration: 0.3) {
            activeView.center = CGPoint(
                x: direction * (screenWidth * 1.5),
                y: activeView.center.y + velocity.y * 0.1
            )
            activeView.alpha = 0
        } completion: { _ in
            self.recycleView()
        }
    }
    
    private func resetViewPosition(_ view: PhotosRemoveBaseView) {
        UIView.animate(withDuration: 0.3) {
            view.transform = .identity
            view.frame = CGRectMake(0, 0, self.view.width - 30, 509 * RScreenH())
            view.center = self.view.center
            view.hideButtons()
        }
        initTrashAndKeepListButton()
    }
    
    private func recycleView() {
        // 移除旧视图
        let removedView = photoViews.removeFirst()
        removedView.removeFromSuperview()
        
        // 当划到最后一张的时候就不再滑动了
        let tempIndex = dataModel.count - 1
        // 表示滑动结束了
        if currentIndex == tempIndex {
            DispatchQueue.main.async {
                self.navigationController?.popViewController(animated: true)
            }
            return
        }
        
        // 创建新视图并更新内容
        let newView = PhotosRemoveBaseView()
        newView.frame = CGRectMake(0, 0, self.view.width - 30, 509 * RScreenH())
        newView.center = self.view.center
        newView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan)))
        newView.alpha = 0
        view.addSubview(newView)
        
        photoViews.append(newView)
        
        // 更新索引并加载新内容
        currentIndex = (currentIndex + 1) % dataModel.count
        updateViewContents()
        
        // 视图层级处理
        bringCurrentViewToFront()
        newView.alpha = 1
        initTrashAndKeepListButton()
    }
    
    func initTrashAndKeepListButton(){
        self.trashButton.isSelected = false
        self.keepListButton.isSelected = false
        self.view.bringSubviewToFront(self.trashButton)
        self.view.bringSubviewToFront(self.keepListButton)
    }
    
    private func bringCurrentViewToFront() {
        guard photoViews.count >= 2 else { return }
        view.bringSubviewToFront(photoViews[1])
        view.bringSubviewToFront(photoViews[0])
        view.bringSubviewToFront(self.trashButton)
        view.bringSubviewToFront(self.keepListButton)
    }
    
    
    private func getVideoURLFromLocalIdentifier(localIdentifier: String, completion: @escaping (URL?, Error?) -> Void) {
        // 通过 localIdentifier 获取 PHAsset
        let fetchOptions = PHFetchOptions()
        let assets = PHAsset.fetchAssets(withLocalIdentifiers: [localIdentifier], options: fetchOptions)
        guard let asset = assets.firstObject, asset.mediaType == .video else {
            DispatchQueue.main.async {
                completion(nil, NSError(domain: "com.example.error", code: 1, userInfo: [NSLocalizedDescriptionKey: "未找到对应视频资源"]))
            }
            return
        }

        let options = PHVideoRequestOptions()
        options.isNetworkAccessAllowed = true // 允许从网络下载
        options.deliveryMode = .automatic // 要求高质量格式
        
        PHImageManager.default().requestAVAsset(forVideo: asset, options: options) { (avAsset, audioMix, info) in
            if let error = info?[PHImageErrorKey] as? Error {
                DispatchQueue.main.async {
                    completion(nil, error)
                }
                return
            }
            
            if let urlAsset = avAsset as? AVURLAsset {
                DispatchQueue.main.async {
                    completion(urlAsset.url, nil)
                }
            } else {
                DispatchQueue.main.async {
                    completion(nil, NSError(domain: "CustomErrorDomain", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to get video URL"]))
                }
            }
        }
    }
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}
