//   HomeViewController.swift
//  PaiAi//
//  Created by zhengjianfei on 16/3/28.
//  Copyright © 2016年 FFIB. All rights reserved.
//

import UIKit
import RxSwift
import RxCocoa
import RxDataSources
import PaiaiDataKit
import PaiaiUIKit
import PullToRefresh

final class HomeViewController: UIViewController {

    @IBOutlet weak var scanBtn: UIButton!
    @IBOutlet weak var createBtn: UIButton!
    @IBOutlet weak var collectionView: UICollectionView!
    // MARK: data property
    fileprivate let disposeBag = DisposeBag()
    
    internal var viewModel: HomeViewModel!
    internal var userInfoViewModel: UserInfoViewModel!

    override func viewDidLoad() {
        super.viewDidLoad()
        initalize()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    }
    
    func initalize() {
        collectionView.register(UINib(nibName: "PhotoCell",
                                      bundle: Bundle(identifier: "com.Paiai-iOS")),
                                forCellWithReuseIdentifier: "photoCell")
        
        setup()
        binding()
    }
    
    private func setup() {
        setupReloadControl()
        setupLoadingControl()
    }
    
    private func setupReloadControl() {
        collectionView.addPullToRefresh(PullToRefresh()) {
            [unowned self] in
            self.viewModel.reload()
        }
    }
    
    private func setupLoadingControl() {
        collectionView.addPullToRefresh(PullToRefresh(position: .bottom)) {
            [weak self] in
            guard let `self` = self else { return }
            self.viewModel.preload()
        }
    }
}

/// UI bindings
fileprivate extension HomeViewController {
    
    var dataSource: RxCollectionViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, PhotoItem>> {
        return RxCollectionViewSectionedAnimatedDataSource<AnimatableSectionModel<Int, PhotoItem>>(configureCell:
            { (dataSource, collectionView, indexPath, item) -> UICollectionViewCell in
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoCell", for: indexPath) as! PhotoCell
            cell.setInfo(item, source: .home)
            return cell
        })
    }
    
    func binding() {
        bindInteraction()
        bindViewModelToRefreshing()
        bindCollectionViewDelegate()
        bindUserInfoViewModelToView()
        bindViewModelToCollectionView()
        bindCollectionViewToViewModel()
    }
    
    func bindInteraction() {
        createBtn.rx.tap.bind(to: viewModel.createBtnTapped).disposed(by: disposeBag)
        scanBtn.rx.tap.bind(to: viewModel.scanBtnTapped).disposed(by: disposeBag)
    }
    
    func bindViewModelToRefreshing() {
        viewModel.isLoading
            .subscribe(onNext: {[unowned self] flag in
                if flag {
                    self.collectionView.endRefreshing(at: .top)
                } else {
                    self.collectionView.endRefreshing(at: .bottom)
                }
            }).disposed(by: disposeBag)
    }
    
    func bindCollectionViewDelegate() {
        collectionView.rx.setDelegate(self).disposed(by: disposeBag)
    }
    
    func bindUserInfoViewModelToView() {
        userInfoViewModel.isLoggedIn
            .asDriver(onErrorJustReturn: ())
            .drive(onNext: { (_) in
                self.collectionView.startRefreshing(at: .top)
            }).disposed(by: disposeBag)
    }
    
    func bindViewModelToCollectionView() {
        viewModel.contents
            .bind(to: collectionView.rx.items(dataSource: dataSource))
            .disposed(by: disposeBag)
    }
    
    func bindCollectionViewToViewModel() {
        collectionView.rx.willDisplayCell
            .asDriver()
            .drive(onNext: { [unowned self] in self.preload(indexPath: $0.at) })
            .disposed(by: disposeBag)
        
        collectionView.rx.itemSelected
            .asDriver(onErrorJustReturn: IndexPath(item: 0, section: 0))
            .drive(onNext: { [unowned self] in self.viewModel.didSelect($0.row) } )
            .disposed(by: disposeBag)
    }
    
    func preload(indexPath: IndexPath) {
        guard indexPath.row == collectionView.numberOfItems(inSection: 0) - 5 else { return }
        collectionView.startRefreshing(at: .bottom)
    }
}

extension HomeViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        sizeForItemAt indexPath: IndexPath) -> CGSize {
        return viewModel.layoutSizeForIndexPath(indexPath)
    }
}