//
//  PQPhotoMaterialController.swift
//  PQSpeed
//
//  Created by SanW on 2021/4/26.
//  Copyright © 2021 BytesFlow. All rights reserved.
//

import Photos
import UIKit

class PQPhotoMaterialController: PQBaseViewController {
    // 是否显示素材标识
    var isShowMediaTag: Bool = true
    // 是否是已经添加过的素材
    var isAdded: Bool = false
    // 默认图片时长
    var imageDuration: Float64 = 2.0
    // 已选图片时长
    var selectedImageDataCount: Int = 0
    var itemSpacing: CGFloat = cDefaultMargin / 2 // 间隔
    var itemSize = CGSize(width: (cScreenWidth - cDefaultMargin) / 3, height: (cScreenWidth - cDefaultMargin) / 3) // cell 大小
    var previousPreheatRect = CGRect.zero

    var allPhotos: PHFetchResult<PHAsset> = PHFetchResult<PHAsset>.init() // 所有的图片
    var photoData: [PQEditVisionTrackMaterialsModel] = Array<PQEditVisionTrackMaterialsModel>.init() // 相册数据
    // 选中的相册数据
    var selectedPhotoData: [PQEditVisionTrackMaterialsModel] = Array<PQEditVisionTrackMaterialsModel>.init()
    // 选中的总时长
    var selectedTotalDuration: Float64 = 0

    var selectedMaterialHandle: ((_ currentMaterialData: PQEditVisionTrackMaterialsModel?, _ selectedPhotoData: [PQEditVisionTrackMaterialsModel], _ selectedTotalDuration: Float64, _ imageCount: Int) -> Void)? // 选中/取消选中的回调
    var detailMaterialHandle: ((_ indexPath: IndexPath, _ currentMaterialData: PQEditVisionTrackMaterialsModel?) -> Void)? // 点击详情
    /// 滑动的回调
    var scrollViewDidScroll: ((_ contentOffset: CGPoint) -> Void)?
    /// 空白页面点击的回调
    var emptyRefreshHandle: ((_ msgType: material_msgType) -> Void)?
    var msgType: material_msgType = .all { // 默认类型
        didSet {
            photoData.removeAll()
            allPhotos = PHFetchResult<PHAsset>.init()
            photoCollectionView.setContentOffset(CGPoint.zero, animated: false)
            photoCollectionView.reloadData()
            loadLocalData()
        }
    }

    var assetCollection: PHAssetCollection? // 相簿
    lazy var imageManager: PHCachingImageManager = { // 图库缓存管理
        (PHCachingImageManager.default() as? PHCachingImageManager) ?? PHCachingImageManager()
    }()

    lazy var photoFlowLayout: UICollectionViewFlowLayout = {
        let photoFlowLayout = UICollectionViewFlowLayout()
        photoFlowLayout.sectionInset = UIEdgeInsets.zero
        photoFlowLayout.minimumLineSpacing = itemSpacing
        photoFlowLayout.minimumInteritemSpacing = itemSpacing
        photoFlowLayout.scrollDirection = .vertical
        photoFlowLayout.itemSize = itemSize
        return photoFlowLayout
    }()

    lazy var photoCollectionView: UICollectionView = {
        let photoCollectionView = UICollectionView(frame: CGRect(x: itemSpacing, y: 0, width: view.frame.width, height: view.frame.height), collectionViewLayout: photoFlowLayout)
        photoCollectionView.register(PQChoseMaterialCell.self, forCellWithReuseIdentifier: String(describing: PQChoseMaterialCell.self))
        photoCollectionView.showsVerticalScrollIndicator = false
        photoCollectionView.showsHorizontalScrollIndicator = false
        photoCollectionView.delegate = self
        photoCollectionView.dataSource = self
        photoCollectionView.backgroundColor = UIColor.clear
        if #available(iOS 11.0, *) {
            photoCollectionView.contentInsetAdjustmentBehavior = .never
        } else {
            automaticallyAdjustsScrollViewInsets = false
        }
        return photoCollectionView
    }()

    var anthorEmptyData: PQEmptyModel = {
        let anthorEmptyData = PQEmptyModel()
        anthorEmptyData.title = "挑选相册素材"
        anthorEmptyData.summary = "要挑选相册素材，请先授予相册使用权限"
        anthorEmptyData.emptyImage = "icon_authorError"
        anthorEmptyData.isRefreshHidden = false
        anthorEmptyData.refreshBgColor = UIColor.hexColor(hexadecimal: PQBFConfig.shared.styleColor.rawValue)
        return anthorEmptyData
    }()

    var emptyData: PQEmptyModel = {
        let emptyData = PQEmptyModel()
        emptyData.title = "此相册中什么都没有"
        emptyData.isRefreshHidden = false
        emptyData.refreshTitle = NSMutableAttributedString(string: "刷新")
        emptyData.refreshBgColor = UIColor.hexColor(hexadecimal: PQBFConfig.shared.styleColor.rawValue)
        emptyData.emptyImage = "material_empty"
        return emptyData
    }()

    lazy var emptyRemindView: PQEmptyRemindView = {
        let emptyRemindView = PQEmptyRemindView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height))
        emptyRemindView.isHidden = true
        photoCollectionView.addSubview(emptyRemindView)
        emptyRemindView.backgroundColor = PQBFConfig.shared.styleBackGroundColor
        emptyRemindView.fullRefreshBloc = { [weak self] _, _ in
            if emptyRemindView.refreshBtn.currentTitle == "授予权限" {
                openAppSetting()
            } else if emptyRemindView.refreshBtn.currentAttributedTitle == NSMutableAttributedString(string: "刷新") {
                self?.loadLocalData()
            } else if self?.emptyRefreshHandle != nil {
                self?.emptyRefreshHandle!(self?.msgType ?? .all)
            }
        }
        emptyRemindView.remindLab.textColor = UIColor.hexColor(hexadecimal: "#999999")
        emptyRemindView.refreshBtn.addCorner(corner: 4)
        return emptyRemindView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(photoCollectionView)
        hiddenNavigation()
        view.backgroundColor = PQBFConfig.shared.styleBackGroundColor
    }

    /// <#Description#>
    /// - Returns: <#description#>
    func loadLocalData() {
        let authStatus = PHPhotoLibrary.authorizationStatus()
        if authStatus == .notDetermined {
            // 第一次触发授权 alert
            PHPhotoLibrary.requestAuthorization { [weak self] (status: PHAuthorizationStatus) -> Void in
                if status == .authorized {
                    if (self?.allPhotos == nil) || (self?.allPhotos.count ?? 0) <= 0 {
                        self?.loadPhotoData()
                    }
                }
                DispatchQueue.main.async { [weak self] in
                    self?.showEmpthView()
                }
            }
        } else if authStatus == .authorized {
            BFLog(message: "授权成功，开始请求相册数据-\(allPhotos)")
//            if allPhotos.count <= 0 {
            loadPhotoData()
//            }
        } else {
            showEmpthView()
        }
        PHPhotoLibrary.shared().register(self)
    }

    /// 加载图库数据
    /// - Returns: <#description#>
    func loadPhotoData() {
        DispatchQueue.main.async { [weak self] in
            PQLoadingHUB.shared.showHUB(superView: self!.view, isVerticality: false)
        }
        DispatchQueue.global().async { [weak self] in
            self?.allPhotos = self?.assetCollection != nil ? PHAsset.fetchAssets(in: (self?.assetCollection)!, options: self?.fetchOptions()) : PHAsset.fetchAssets(with: self?.fetchOptions())
            DispatchQueue.main.async { [weak self] in
                if self?.view != nil {
                    PQLoadingHUB.shared.dismissHUB(superView: self!.view)
                }
                self?.photoCollectionView.reloadData()
                self?.showEmpthView()
//                self?.updateCachedAssets()
            }
        }
    }

    /// 获取option
    /// - Returns: <#description#>
    func fetchOptions() -> PHFetchOptions {
        if msgType != .all {
            let fetchOptions = PHFetchOptions()
            fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
            fetchOptions.predicate = NSPredicate(format: "mediaType = %d", msgType == .video ? PHAssetMediaType.video.rawValue : PHAssetMediaType.image.rawValue)
            return fetchOptions
        } else {
            return creaFetchOptions
        }
    }

    /// 展示空页面
    func showEmpthView() {
        emptyRemindView.isHidden = allPhotos.count > 0
        if !emptyRemindView.isHidden {
            let authStatus = PHPhotoLibrary.authorizationStatus()
            if authStatus == .denied {
                emptyRemindView.emptyData = anthorEmptyData
                emptyRemindView.refreshBtn.setTitle("授予权限", for: .normal)
            } else {
                switch msgType {
                case .video:
                    emptyData.title = "此相册中没有视频"
                    emptyData.emptyImage = "stuckPoint_video_empty"
                    emptyData.refreshTitle = NSMutableAttributedString(string: "去选照片")
                case .image:
                    emptyData.title = "此相册中没有照片"
                    emptyData.emptyImage = "stuckPoint_image_empty"
                    emptyData.refreshTitle = NSMutableAttributedString(string: "去选视频")
                default:
                    emptyData.title = "此相册中什么都没有"
                    emptyData.emptyImage = "material_empty"
                    emptyData.refreshTitle = NSMutableAttributedString(string: "刷新")
                }
                emptyData.summary = nil
                emptyRemindView.emptyData = emptyData
            }
        }
    }

    /// 更新frame
    /// - Parameter newFrame: <#newFrame description#>
    /// - Returns: <#description#>
    func updateFrame(newFrame: CGRect, isAnimate: Bool = false, isScroll _: Bool = false) {
        if isAnimate {
            UIView.animate(withDuration: 0.5, delay: 0, options: .allowUserInteraction) { [weak self] in
                // 调整位置
                self?.view.frame = newFrame
                self?.photoCollectionView.frame = self?.view.bounds ?? CGRect.zero
                self?.emptyRemindView.frame = self?.photoCollectionView.bounds ?? CGRect.zero
            } completion: { _ in
            }
        } else {
            view.frame = newFrame
            photoCollectionView.frame = view.bounds
            emptyRemindView.frame = photoCollectionView.bounds
        }
    }
}

extension PQPhotoMaterialController: UICollectionViewDelegate, UICollectionViewDataSource, UIScrollViewDelegate {
    func collectionView(_: UICollectionView, numberOfItemsInSection _: Int) -> Int {
        return allPhotos.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = PQChoseMaterialCell.choseMaterialCell(collectionView: collectionView, indexPath: indexPath)
        cell.isShowMediaTag = isShowMediaTag
        cell.isAdded = isAdded
        if photoData.count <= indexPath.item {
            let itemData: PQEditVisionTrackMaterialsModel!
            let asset = allPhotos.object(at: indexPath.item)
            let selectedItem = selectedPhotoData.first { (item) -> Bool in
                item.asset == asset
            }
            if selectedItem != nil {
                itemData = selectedItem
            } else {
                itemData = PQEditVisionTrackMaterialsModel()
                itemData.downloadState = .compelte
                itemData.asset = asset
                itemData.height = Float(itemData.asset?.pixelHeight ?? 0)
                itemData.width = Float(itemData.asset?.pixelWidth ?? 0)
                itemData.type = asset.mediaType == .image ? StickerType.IMAGE.rawValue : StickerType.VIDEO.rawValue
                itemData.volumeGain = asset.mediaType == .image ? 0 : 100
                itemData.duration = asset.mediaType == .image ? imageDuration : asset.duration
                itemData.out = itemData.duration
            }
            photoData.append(itemData)
        }
        if photoData.count > indexPath.item {
            let itemData = photoData[indexPath.item]
            cell.materialData = itemData
            cell.representedAssetIdentifier = itemData.asset?.localIdentifier
            if itemData.coverImageUI == nil, itemData.asset != nil {
                imageManager.requestImage(for: itemData.asset!, targetSize: itemSize, contentMode: .aspectFill, options: nil) { image, info in
                    if info?.keys.contains("PHImageResultIsDegradedKey") ?? false, "\(info?["PHImageResultIsDegradedKey"] ?? "0")" == "0", cell.representedAssetIdentifier == itemData.asset?.localIdentifier {
                        if image != nil {
                            itemData.coverImageUI = image
                            cell.materialImageView.image = image
                        } else if image == nil, info?.keys.contains("PHImageResultIsInCloudKey") ?? false {
                            let option = PHImageRequestOptions()
                            option.isNetworkAccessAllowed = true
                            option.resizeMode = .fast
                            self.imageManager.requestImageData(for: itemData.asset!, options: option) { data, _, _, _ in
                                if data != nil {
                                    let image = UIImage(data: data!)
                                    itemData.coverImageUI = image
                                    cell.materialImageView.image = image
                                }
                            }
                        }
                    }
                }
            }
        } else {
            cell.materialData = PQEditVisionTrackMaterialsModel()
        }
        cell.materialClicHandle = { [weak self] _, materialData in
            if (self?.photoData.count ?? 0) > indexPath.item {
                // 处理相册选择
                self?.dealWithSelectedMaterial(indexPath: indexPath, materialData: materialData)
            } else {
//                collectionView.reloadData()
            }
        }
        return cell
    }

    func collectionView(_: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if photoData.count <= indexPath.item {
//            collectionView.reloadData()
            return
        }
        if detailMaterialHandle != nil {
            detailMaterialHandle!(indexPath, photoData[indexPath.item])
        }
    }

    func collectionView(_: UICollectionView, willDisplay _: UICollectionViewCell, forItemAt _: IndexPath) {
        if !isAdded, !isShowMediaTag {
//            // 卡点音乐素材选择曝光上报
//            PQEventTrackViewModel.baseReportUpload(businessType: .bt_windowView, objectType: .ot_view_selectSyncedUpMaterial, pageSource: .sp_stuck_selectMaterial, extParams: nil, remindmsg: "卡点音乐素材选择曝光上报")
        }
    }

    /// 点击选择的回调
    /// - Parameter materialData: <#materialData description#>
    /// - Returns: description
    func dealWithSelectedMaterial(indexPath: IndexPath?, materialData: PQEditVisionTrackMaterialsModel?) {
        let ratio = (materialData?.width ?? 0) / (materialData?.height ?? 1)
        if ratio < 0.4 || ratio > 4.2 {
            cShowHUB(superView: nil, msg: "暂不支持该比例的素材")
            return
        }
        if materialData != nil, indexPath != nil {
            materialData?.isSelected = !(materialData?.isSelected ?? false)
            if materialData?.isSelected ?? false {
                selectedPhotoData.append(materialData!)
                if materialData?.type == StickerType.IMAGE.rawValue {
                    selectedImageDataCount = selectedImageDataCount + 1
                }
                materialData?.selectedIndex = selectedPhotoData.count
                if materialData?.asset != nil && materialData?.asset?.mediaType != .video && (materialData?.coverImageUI == nil || (materialData?.locationPath.count ?? 0) <= 0) {
                    PQPHAssetVideoParaseUtil.requestAssetOringinImage(asset: (materialData?.asset)!) { [weak self] _, data, image, _ in
                        if image == nil {
                            BFLog(message: "图片数据为空！！！！！")
                        }
                        // 1,图片，gif的原文件数据,和视频的封面
                        var newImage: UIImage?
                        if image != nil {
                            newImage = UIImage.nx_fixOrientation(image, isFront: false).nx_scaleWithMaxLength(maxLength: 1920)
                        }
                        materialData?.coverImageUI = newImage
                        materialData?.originalData = data
                        let timeInterval: TimeInterval = Date().timeIntervalSince1970
                        let imageCacheName = "images_\(timeInterval)"
                        let imageCachePath = downloadImagesDirectory + imageCacheName
                        if !directoryIsExists(dicPath: downloadImagesDirectory) {
                            BFLog(message: "文件夹不存在 \(downloadImagesDirectory)")
                            createDirectory(path: downloadImagesDirectory)
                        }
                        // 创建目录
                        if newImage != nil {
                            try? newImage?.pngData()?.write(to: URL(fileURLWithPath: imageCachePath))
                        } else {
                            try? data?.write(to: URL(fileURLWithPath: imageCachePath))
                        }
                        if materialData?.asset?.mediaType != .video, newImage != nil || data != nil {
                            materialData?.locationPath = imageCachePath.replacingOccurrences(of: documensDirectory, with: "")
                        }
                        materialData?.width = Float(materialData?.asset?.pixelWidth ?? 0)
                        materialData?.height = Float(materialData?.asset?.pixelHeight ?? 0)
                        if self?.selectedMaterialHandle != nil {
                            self?.selectedTotalDuration = (self?.selectedTotalDuration ?? 0) + (materialData?.duration ?? 0.0)
                            if indexPath != nil {
                                self?.photoCollectionView.reloadItems(at: [indexPath!])
                            }
                            // 处理已选择的数据
                            self?.dealWithSelectedData(materialData: materialData)
                        }
                    }
                } else {
                    selectedTotalDuration = selectedTotalDuration + (materialData?.duration ?? 0.0)
                    if indexPath != nil {
                        photoCollectionView.reloadItems(at: [indexPath!])
                    }
                    // 处理已选择的数据
                    dealWithSelectedData(materialData: materialData)
                }
            } else {
                // 处理取消选择数据
                deSeletedMaterialData(materialData: materialData)
            }
        }
    }

    /// 处理取消选择数据
    /// - Parameter materialData: <#materialData description#>
    /// - Returns: <#description#>
    func deSeletedMaterialData(materialData: PQEditVisionTrackMaterialsModel?) {
        selectedPhotoData.removeAll(where: { (item) -> Bool in
            item.asset == materialData?.asset
        })
        for item in photoData {
            if item.isSelected, item.selectedIndex > (materialData?.selectedIndex ?? 1) {
                item.selectedIndex = item.selectedIndex - 1
            }
        }
        if materialData?.type == StickerType.IMAGE.rawValue {
            selectedImageDataCount = selectedImageDataCount - 1
        }
        selectedTotalDuration = selectedTotalDuration - (materialData?.duration ?? 0.0)
        photoCollectionView.reloadData()
        // 处理已选择的数据
        dealWithSelectedData(materialData: materialData)
    }

    /// 处理已选择的数据
    /// - Parameters:
    ///   - indexPath: <#indexPath description#>
    ///   - materialData: <#materialData description#>
    /// - Returns: <#description#>
    func dealWithSelectedData(materialData: PQEditVisionTrackMaterialsModel?) {
//        if materialData?.asset != nil && materialData?.asset?.mediaType == .video && (materialData?.locationPath == nil || (materialData?.locationPath.count ?? 0) <= 0) {
//            PQPHAssetVideoParaseUtil.parasToAVAsset(phAsset: (materialData?.asset)!) { [weak self] avAsset, _, _, _ in
//                if avAsset is AVURLAsset {
//                    materialData?.locationPath = (avAsset as? AVURLAsset)?.url.absoluteString.replacingOccurrences(of: "file:///", with: "") ?? ""
//                    if self?.selectedMaterialHandle != nil {
//                        DispatchQueue.main.async {
//                            self?.selectedMaterialHandle!(materialData, self?.selectedPhotoData ?? [], self?.selectedTotalDuration ?? 0)
//                        }
//                    }
//                } else if self?.selectedMaterialHandle != nil {
//                    DispatchQueue.main.async {
//                        self?.selectedMaterialHandle!(materialData, self?.selectedPhotoData ?? [], self?.selectedTotalDuration ?? 0)
//                    }
//                }
//            }
//        } else
        if selectedMaterialHandle != nil {
            selectedMaterialHandle!(materialData, selectedPhotoData, selectedTotalDuration, selectedImageDataCount)
        }
    }

    /// <#Description#>
    /// - Parameter scrollView: <#scrollView description#>
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if scrollViewDidScroll != nil {
            scrollViewDidScroll!(scrollView.contentOffset)
        }
    }

    /// 更新数据
    /// - Parameter isMaterialSelected:
    /// - Parameter materialData: <#materialData description#>
    /// - Returns: <#description#>
    func updateMaterials(isSelected: Bool, materialData: PQEditVisionTrackMaterialsModel?) {
        let photoIndexPath = selectedPhotoData.firstIndex { (item) -> Bool in
            materialData?.asset == item.asset
        }
        materialData?.isSelected = isSelected
        if isSelected {
            if photoIndexPath == nil {
                selectedPhotoData.append(materialData!)
            }
            materialData?.selectedIndex = selectedPhotoData.count
            selectedTotalDuration = selectedTotalDuration + (materialData?.duration ?? 0.0)
        } else if photoIndexPath != nil {
            selectedPhotoData.remove(at: photoIndexPath ?? 0)
            for item in selectedPhotoData {
                if item.isSelected, item.selectedIndex > (materialData?.selectedIndex ?? 1) {
                    item.selectedIndex = item.selectedIndex - 1
                }
            }
            selectedTotalDuration = selectedTotalDuration - (materialData?.duration ?? 0.0)
        }
        photoCollectionView.reloadData()
        if selectedMaterialHandle != nil {
            selectedMaterialHandle!(materialData, selectedPhotoData, selectedTotalDuration, selectedImageDataCount)
        }
    }
}

extension PQPhotoMaterialController: PHPhotoLibraryChangeObserver {
    func photoLibraryDidChange(_ changeInstance: PHChange) {
        DispatchQueue.main.sync {
            // Check each of the three top-level fetches for changes.
            guard let collectionChanges = changeInstance.changeDetails(for: allPhotos)
            else {
                return
            }
            if !collectionChanges.hasIncrementalChanges || collectionChanges.hasMoves {
                return
            }
            // Update the cached fetch result.
            allPhotos = collectionChanges.fetchResultAfterChanges
            photoData.removeAll()
            photoCollectionView.reloadData()
//            photoCollectionView.setContentOffset(CGPoint.zero, animated: false)
        }
    }

    private func resetCachedAssets() {
        imageManager.stopCachingImagesForAllAssets()
        previousPreheatRect = .zero
    }

    private func updateCachedAssets() {
        if allPhotos.count <= 0 {
            return
        }
        guard isViewLoaded, view.window != nil else { return }
        let visibleRect = CGRect(origin: photoCollectionView.contentOffset, size: photoCollectionView.bounds.size)
        let preheatRect = visibleRect.insetBy(dx: 0, dy: -0.5 * visibleRect.height)
        let delta = abs(preheatRect.midY - previousPreheatRect.midY)
        guard delta > view.bounds.height / 3 else { return }
        let (addedRects, removedRects) = differencesBetweenRects(previousPreheatRect, preheatRect)
        let addedAssets: [PHAsset]? = addedRects
            .flatMap { rect in photoCollectionView.indexPathsForElements(in: rect) }
            .map { indexPath in
                if indexPath.item < allPhotos.count {
                    return allPhotos.object(at: indexPath.item)
                } else {
                    return PHAsset()
                }
            }
        let removedAssets: [PHAsset]? = removedRects
            .flatMap { rect in photoCollectionView.indexPathsForElements(in: rect) }
            .map { indexPath in
                if indexPath.item < allPhotos.count {
                    return allPhotos.object(at: indexPath.item)
                } else {
                    return PHAsset()
                }
            }
        if addedAssets != nil, (addedAssets?.count ?? 0) > 0 {
            imageManager.startCachingImages(for: addedAssets!,
                                            targetSize: itemSize, contentMode: .aspectFill, options: nil)
        }
        if removedAssets != nil, (removedAssets?.count ?? 0) > 0 {
            imageManager.stopCachingImages(for: removedAssets!,
                                           targetSize: itemSize, contentMode: .aspectFill, options: nil)
        }
        previousPreheatRect = preheatRect
    }

    private func differencesBetweenRects(_ old: CGRect, _ new: CGRect) -> (added: [CGRect], removed: [CGRect]) {
        if old.intersects(new) {
            var added = [CGRect]()
            if new.maxY > old.maxY {
                added += [CGRect(x: new.origin.x, y: old.maxY,
                                 width: new.width, height: new.maxY - old.maxY)]
            }
            if old.minY > new.minY {
                added += [CGRect(x: new.origin.x, y: new.minY,
                                 width: new.width, height: old.minY - new.minY)]
            }
            var removed = [CGRect]()
            if new.maxY < old.maxY {
                removed += [CGRect(x: new.origin.x, y: new.maxY,
                                   width: new.width, height: old.maxY - new.maxY)]
            }
            if old.minY < new.minY {
                removed += [CGRect(x: new.origin.x, y: old.minY,
                                   width: new.width, height: new.minY - old.minY)]
            }
            return (added, removed)
        } else {
            return ([new], [old])
        }
    }
}
