//
//  AccountListViewController.swift
//  Tusker
//
//  Created by Shadowfacts on 9/5/19.
//  Copyright © 2019 Shadowfacts. All rights reserved.
//

import UIKit

class AccountListViewController: UIViewController, CollectionViewController {
    typealias Item = String
    
    private let mastodonController: MastodonController
    private let accountIDs: [String]
    
    var collectionView: UICollectionView! {
        view as? UICollectionView
    }
    private var dataSource: UICollectionViewDiffableDataSource<Section, Item>!
    
    init(accountIDs: [String], mastodonController: MastodonController) {
        self.mastodonController = mastodonController
        self.accountIDs = accountIDs
        
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func loadView() {
        var config = UICollectionLayoutListConfiguration(appearance: .grouped)
        config.backgroundColor = .appGroupedBackground
        let layout = UICollectionViewCompositionalLayout { sectionIndex, environment in
            let section = NSCollectionLayoutSection.list(using: config, layoutEnvironment: environment)
            section.readableContentInset(in: environment)
            return section
        }
        view = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.delegate = self
        collectionView.dragDelegate = self
        collectionView.allowsFocus = true
        dataSource = createDataSource()
    }
    
    private func createDataSource() -> UICollectionViewDiffableDataSource<Section, Item> {
        let accountCell = UICollectionView.CellRegistration<AccountCollectionViewCell, String> { [unowned self] cell, indexPath, item in
            cell.delegate = self
            cell.updateUI(accountID: item)
        }
        return UICollectionViewDiffableDataSource(collectionView: collectionView) { collectionView, indexPath, itemIdentifier in
            return collectionView.dequeueConfiguredReusableCell(using: accountCell, for: indexPath, item: itemIdentifier)
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
        snapshot.appendSections([.accounts])
        snapshot.appendItems(accountIDs)
        dataSource.apply(snapshot, animatingDifferences: false)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        clearSelectionOnAppear(animated: animated)
    }
}

extension AccountListViewController {
    enum Section {
        case accounts
    }
}

extension AccountListViewController: UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if let id = dataSource.itemIdentifier(for: indexPath) {
            selected(account: id)
        }
    }
    
    func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
        guard let id = dataSource.itemIdentifier(for: indexPath),
              let cell = collectionView.cellForItem(at: indexPath) else {
            return nil
        }
        return UIContextMenuConfiguration {
            ProfileViewController(accountID: id, mastodonController: self.mastodonController)
        } actionProvider: { _ in
            UIMenu(children: self.actionsForProfile(accountID: id, source: .view(cell)))
        }
    }
    
    func collectionView(_ collectionView: UICollectionView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) {
        MenuPreviewHelper.willPerformPreviewAction(animator: animator, presenter: self)
    }
}

extension AccountListViewController: UICollectionViewDragDelegate {
    func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
        guard let id = dataSource.itemIdentifier(for: indexPath),
              let currentAccountID = mastodonController.accountInfo?.id,
              let account = mastodonController.persistentContainer.account(for: id) else {
            return []
        }
        let provider = NSItemProvider(object: account.url as NSURL)
        let activity = UserActivityManager.showProfileActivity(id: id, accountID: currentAccountID)
        activity.displaysAuxiliaryScene = true
        provider.registerObject(activity, visibility: .all)
        return [UIDragItem(itemProvider: provider)]
    }
}

extension AccountListViewController: TuskerNavigationDelegate {
    var apiController: MastodonController! { mastodonController }
}

extension AccountListViewController: MenuActionProvider {
}

extension AccountListViewController: StatusBarTappableViewController {
    func handleStatusBarTapped(xPosition: CGFloat) -> StatusBarTapActionResult {
        collectionView.scrollToTop()
        return .stop
    }
}
