//
//  ListInteractor.swift
//  Swiftmazing
//
//  Created by Hélio Mesquita on 14/12/19.
//  Copyright (c) 2019 Hélio Mesquita. All rights reserved.
//
//  This file was generated by the Clean Swift Xcode Templates so
//  you can apply clean architecture to your iOS and Mac projects,
//  see http://clean-swift.com
//
// This tag below is used to create the testable files from the Cuckoo pod
// CUCKOO_TESTABLE

import Infrastructure
import UIKit

protocol ListBusinessLogic {
    func loadScreen()
    func reloadRepositories()
    func repositorySelected(_ repository: Repository?)
    func prefetchNextPage(index: Int)
}

protocol ListDataStore {
    var selectedRepository: Repository? { get set }
    var listFilter: Filter { get set }
    var listTitle: String { get set }
    var listRepositories: [Repository] { get set }
}

class ListInteractor: ListBusinessLogic, ListDataStore {

    let worker: RepositoriesWorker
    let itemsPerPage: Int
    var presenter: ListPresentationLogic?
    var currentPage: Int = 1

    // MARK: DATASTORE
    var selectedRepository: Repository?
    var listTitle: String = ""
    var listFilter: Filter = .none
    var listRepositories: [Repository] = []

    init(worker: RepositoriesWorker = RepositoriesWorker(), itemsPerPage: Int = RepositoriesProvider.itemsPerPage) {
        self.worker = worker
        self.itemsPerPage = itemsPerPage
    }

    func loadScreen() {
        presenter?.presentTitle(listTitle)
        presenter?.reloadMap(listRepositories)
    }

    func reloadRepositories() {
        currentPage = 1
        worker.getRepositories(with: listFilter, page: currentPage).done(handleReloadSuccess).catch(handleError)
    }

    private func handleReloadSuccess(_ repositories: Repositories) {
        presenter?.reloadMap(repositories.items)
    }

    func repositorySelected(_ repository: Repository?) {
        selectedRepository = repository
        presenter?.presentDetail()
    }

    func prefetchNextPage(index: Int) {
        let indexAdjusted = index + 1
        let totalItems = currentPage * itemsPerPage
        if indexAdjusted == totalItems {
            loadNextPage()
        }
    }

    private func loadNextPage() {
        currentPage += 1
        worker.getRepositories(with: listFilter, page: currentPage).done(handleNextSuccess).catch(handleError)
    }

    private func handleNextSuccess(_ repositories: Repositories) {
        presenter?.nextPageMap(repositories.items)
    }

    private func handleError(_ error: Error) {
        presenter?.presentTryAgain(message: (error as? RequestError)?.localizedDescription ?? "")
    }

}
