//
//  SwipeActionsPrefsView.swift
//  Tusker
//
//  Created by Shadowfacts on 11/26/22.
//  Copyright © 2022 Shadowfacts. All rights reserved.
//

import SwiftUI
import TuskerPreferences

struct SwipeActionsPrefsView: UIViewControllerRepresentable {
    @Binding var selection: [StatusSwipeAction]
    
    typealias UIViewControllerType = SwipeActionsPrefsViewController
    
    func makeUIViewController(context: Context) -> SwipeActionsPrefsViewController {
        return SwipeActionsPrefsViewController(selection: $selection)
    }
    
    func updateUIViewController(_ uiViewController: SwipeActionsPrefsViewController, context: Context) {
    }
}

class SwipeActionsPrefsViewController: UIViewController, UICollectionViewDelegate {
    @Binding var selection: [StatusSwipeAction]
    
    private var collectionView: UICollectionView {
        view as! UICollectionView
    }
    private var dataSource: UICollectionViewDiffableDataSource<Section, Item>!
    
    init(selection: Binding<[StatusSwipeAction]>) {
        self._selection = selection
        
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func loadView() {
        let layout = UICollectionViewCompositionalLayout { [unowned self] sectionIndex, environment in
            var config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
            config.backgroundColor = .appGroupedBackground
            if dataSource.sectionIdentifier(for: sectionIndex) == .selected {
                config.headerMode = .supplementary
            }
            return .list(using: config, layoutEnvironment: environment)
        }
        view = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.delegate = self
        dataSource = createDataSource()
    }
    
    private func createDataSource() -> UICollectionViewDiffableDataSource<Section, Item> {
        let listCell = UICollectionView.CellRegistration<UICollectionViewListCell, StatusSwipeAction> { cell, indexPath, item in
            var config = cell.defaultContentConfiguration()
            config.text = item.displayName
            config.image = UIImage(systemName: item.systemImageName)
            cell.contentConfiguration = config
            cell.accessories = [.reorder(displayed: .always)]
            cell.configurationUpdateHandler = { cell, state in
                cell.backgroundConfiguration = .appListGroupedCell(for: state)
            }
        }
        let dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in
            return collectionView.dequeueConfiguredReusableCell(using: listCell, for: indexPath, item: itemIdentifier)
        }
        let headerCell = UICollectionView.SupplementaryRegistration<UICollectionViewListCell>(elementKind: UICollectionView.elementKindSectionHeader) { supplementaryView, elementKind, indexPath in
            var config = supplementaryView.defaultContentConfiguration()
            config.text = "Selected"
            supplementaryView.contentConfiguration = config
        }
        dataSource.supplementaryViewProvider = { collectionView, kind, indexPath in
            return collectionView.dequeueConfiguredReusableSupplementary(using: headerCell, for: indexPath)
        }
        dataSource.reorderingHandlers.canReorderItem = { _ in
            return true
        }
        dataSource.reorderingHandlers.didReorder = { [unowned self] transaction in
            guard let selectedSection = transaction.sectionTransactions.first(where: { $0.sectionIdentifier == .selected }) else {
                return
            }
            self.selection = self.selection.applying(selectedSection.difference)!
        }
        return dataSource
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setEditing(true, animated: false)
        applySnapshot(animated: false)
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        collectionView.deselectItem(at: indexPath, animated: true)
        guard let item = dataSource.itemIdentifier(for: indexPath),
              let section = dataSource.sectionIdentifier(for: indexPath.section) else {
            return
        }
        switch section {
        case .selected:
            selection.removeAll(where: { $0 == item })
        case .remainder:
            selection.append(item)
        }
        applySnapshot(animated: true)
    }
    
    private func applySnapshot(animated: Bool) {
        var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
        snapshot.appendSections([.selected, .remainder])
        snapshot.appendItems(selection, toSection: .selected)
        snapshot.appendItems(StatusSwipeAction.allCases.filter { !selection.contains($0) }, toSection: .remainder)
        dataSource.apply(snapshot, animatingDifferences: animated)
    }
    
    enum Section {
        case selected
        case remainder
    }
    
    typealias Item = StatusSwipeAction
}
