//
//  GroupViewController.swift
//  Paiai_iOS
//
//  Created by FFIB on 16/3/28.
//  Copyright © 2016年 FFIB. All rights reserved.
//

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

final class GroupViewController: UIViewController {

    // MARK: Storyboard property
    @IBOutlet weak var collectionView: UICollectionView!
    @IBOutlet weak var photographBtn: UIButton!
    @IBOutlet weak var emptyView: UIStackView!
    @IBOutlet weak var qrImageView: UIImageView!
    
    // MARK: custom UI property
    var navigationBarView: UIView = {
        let view = UIView()
        view.alpha = 0
        
        return view
    }()
    
    var navigationBarViewTitle: UILabel = {
        let label = UILabel()
        label.textColor = UIColor.white
        
        return label
    }()
    
    var navigationBarViewImage: UIImageView = {
        let image = UIImageView()
        image.cornerRadius = 18
        return image
    }()
    
    // MARK: data property
    var viewModel: GroupViewModel!
    
    fileprivate var navigationViewNotReady = true
    fileprivate let disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        initalize()
    }
    
    func initalize() {
        collectionView.register(UINib(nibName: "PhotoCell",
                                      bundle: Bundle(identifier: "com.Paiai-iOS")),
                                forCellWithReuseIdentifier: "photoCell")
        setup()
        binding()
        setupNavigationBar()
    }
    
    private func setup() {
        setupReloadControl()
    }
    
    private func setupReloadControl() {
        collectionView.addPullToRefresh(PullToRefresh()) {
            [weak self] in
            guard let `self` = self else { return }
            self.viewModel.reload()
        }
        collectionView.startRefreshing(at: .top)
    }
    
    deinit {
        collectionView.endAllRefreshing()
    }
}

/// UI bindings
fileprivate extension GroupViewController {
    
    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: .group)
                return cell
        })
    }
    
    func binding() {
        bindViewModelToEmptyView()
        bindViewModelToQRImageView()
        
        bindViewModelToRefreshing()
        bindCollectionViewDelegate()
        bindViewModelToCollectionView()
        bindCollectionViewToViewModel()
        bindViewModelToNavigationBarImage()
        bindViewModelToNavigationBarTitle()
    }
    
    func bindViewModelToEmptyView() {
        viewModel.hasData.bind(to: emptyView.rx.isHidden).disposed(by: disposeBag)
    }
    
    func bindViewModelToQRImageView() {
        viewModel.groupItem.map { UIImage(qr: "https:api.pai.ai/g/\($0.group_id)") }.bind(to: qrImageView.rx.image).disposed(by: disposeBag)
    }
    
    func bindViewModelToRefreshing() {
        viewModel.isLoading
            .subscribe(onNext: {[unowned self] flag in
                self.collectionView.endRefreshing(at: .top)
            }).disposed(by: disposeBag)
    }
    
    func bindCollectionViewDelegate() {
        collectionView.rx.setDelegate(self).disposed(by: disposeBag)
    }
    
    func bindViewModelToCollectionView() {
        viewModel.contents
            .bind(to: collectionView.rx.items(dataSource: dataSource))
            .disposed(by: disposeBag)
    }
    
    func bindCollectionViewToViewModel() {
        collectionView.rx.itemSelected
            .asDriver()
            .drive(onNext: { [unowned self] in self.viewModel.didSelect($0.item) })
            .disposed(by: disposeBag)
    }
    
    func bindViewModelToNavigationBarTitle() {
        viewModel.groupName.bind(to: navigationBarViewTitle.rx.text).disposed(by: disposeBag)
    }
    
    func bindViewModelToNavigationBarImage() {
        viewModel.groupAvatar
            .subscribe(onNext: {[weak self] (avatar) in
                guard let `self` = self else { return }
                self.navigationBarViewImage.image = UIImage(named: avatar)
        }).disposed(by: disposeBag)
    }
}

extension GroupViewController {
    func setupNavigationBar() {
        guard navigationViewNotReady else { return }
        setRightBarButtonItems()
        constructNaivgationViewHierarchy()
        activateConstraintsNavigation()
        navigationViewNotReady = false
    }
    
    private func constructNaivgationViewHierarchy() {
        navigationItem.titleView = navigationBarView
        navigationBarView.addSubview(navigationBarViewImage)
        navigationBarView.addSubview(navigationBarViewTitle)
    }
    
    private func setRightBarButtonItems() {
        let item = UIBarButtonItem(images: [UIImage(named: "navigation-QR"),
                                            UIImage(named: "navigation-right")],
                                   targets: [self, viewModel!],
                                   actions: [#selector(GroupViewController.presentGroupQR),
                                             #selector(GroupViewModel.navigateToGroupDetail)])
        navigationItem.setRightItem(item)
    }
    
    @objc func presentGroupQR() {
        let groupItem = viewModel.groupItem.value
        let alert = AlertViewController(style: .custom(GroupQRView(groupName: groupItem.group_name,
                                                                   groupAvatar: "Group\(groupItem.group_default_avatar)",
                                                                   groupQR: "https:api.pai.ai/g/\(groupItem.group_id)"),
                                                       AlertAnimator()) )
        presentController(alert)
    }
}

/// navigation bar layout
fileprivate extension GroupViewController {
    
    func activateConstraintsNavigation() {
        activateConstraintsNavigationBarViewImage()
        activateConstraintsNavigationBarViewTitle()
        
        if #available(iOS 11, *) { return }
        navigationBarViewTitle.sizeToFit()
        navigationBarView.frame.size = CGSize(width: navigationBarViewTitle.bounds.size.width + 42, height: 36)
    }
    
    func activateConstraintsNavigationBarViewTitle() {
        navigationBarViewTitle.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            navigationBarViewTitle.centerYAnchor.constraint(equalTo: navigationBarView.centerYAnchor),
            navigationBarViewTitle.widthAnchor.constraint(lessThanOrEqualToConstant: view.width - 200),
            navigationBarViewTitle.trailingAnchor.constraint(equalTo: navigationBarView.trailingAnchor),
            navigationBarViewTitle.leadingAnchor.constraint(equalTo: navigationBarViewImage.trailingAnchor, constant: 6)
            ])
    }
    
    func activateConstraintsNavigationBarViewImage() {
        navigationBarViewImage.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            navigationBarViewImage.widthAnchor.constraint(equalToConstant: 36),
            navigationBarViewImage.heightAnchor.constraint(equalToConstant: 36),
            navigationBarViewImage.topAnchor.constraint(equalTo: navigationBarView.topAnchor),
            navigationBarViewImage.bottomAnchor.constraint(equalTo: navigationBarView.bottomAnchor),
            navigationBarViewImage.leadingAnchor.constraint(equalTo: navigationBarView.leadingAnchor),
            ])
    }
}

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

/// MARK: imagepicker delegate
extension GroupViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    @IBAction func takePhotoAction() {
        let vc = UIImagePickerController()
        #if (arch(i386) || arch(x86_64))
            vc.sourceType = .photoLibrary
        #else
            vc.sourceType = .camera
        #endif
        vc.delegate = self
        present(vc, animated: true, completion: nil)
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        Toast.showActivity(message: "正在上传照片")
        dismiss(animated: true) {
            guard let image = info[.originalImage] as? UIImage,
                let data = image.scaledImage(length: 1280, with: 0.4) else { return }
            self.viewModel.submit(data: data)
        }
        
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        dismiss(animated: true, completion: nil)
    }
}

extension GroupViewController: NavigationBackViewController {}

extension GroupViewController: Storyboarded {
    static func instantiate() -> GroupViewController {
        return UIStoryboard.group.instantiateViewController(type: GroupViewController.self)
    }
}