// // RecipientsViewModel.swift // GME Remit // // Created by InKwon James Kim on 08/08/2019. // Copyright © 2019 Gobal Money Express Co. Ltd. All rights reserved. // import RxSwift import RxCocoa class RecipientsViewModel: ViewModelType { var presenter: RecipientsModuleInterface? struct Input { let fetchTrigger: Driver let refreshTrigger: Driver let addTrigger: Driver let selectTrigger: Driver let editTrigger: Driver let deleteTrigger: Driver let needEditTrigger: Driver let filterText: Driver } struct Output { let recipients: Driver<[Recipient]> let isNeedEdit: Driver let isPartnerChanged: Driver let isError: Driver let isProgress: Driver } private let disposeBag = DisposeBag() private var selectedRecipientID: String? private let recipientsLinker = BehaviorSubject<[Recipient]>(value: []) private let filteredRecipientLinker = BehaviorSubject<[Recipient]>(value: []) private let accountsLinker = BehaviorSubject<[Account]>(value: []) private let editLinker = PublishSubject() private let deleteLinker = PublishSubject() private let progressLinker = PublishSubject() private let errorLinker = PublishSubject() private var selectedRecipient: Recipient? private var isNeedEditRecipient = PublishSubject() private var isPartnerChanged = PublishSubject() func transform(input: Input) -> Output { input .fetchTrigger .drive(onNext: { [weak self] in guard let `self` = self else { return } self.presenter?.fetchRecipients(isRefresh: false) }) .disposed(by: disposeBag) input .refreshTrigger .drive(onNext: { [weak self] in guard let `self` = self else { return } self.presenter?.fetchRecipients(isRefresh: true) }) .disposed(by: disposeBag) let recipients = Observable.combineLatest( recipientsLinker, input.filterText.asObservable() ) { recipients, searchText -> [Recipient] in guard let searchText = searchText, searchText != "" else { return recipients } return recipients.filter {( $0.fullName?.lowercased().contains(searchText.lowercased()) ?? false )} }.asDriverOnErrorJustComplete() input.selectTrigger .withLatestFrom(recipients) { (indexPath, recipients) -> Recipient in return recipients[indexPath.row] } .drive(onNext: { [weak self] in guard let `self` = self else { return } self.selectedRecipient = $0 guard let paymentMode = self.selectedRecipient?.paymentMethod else { self.isNeedEditRecipient.onNext(()) return } if paymentMode.id == nil { self.isNeedEditRecipient.onNext(()) return } if self.selectedRecipient?.isPartnerChanged == "1" { self.isPartnerChanged.onNext(()) return } let accounts = try? self.accountsLinker.value() self.presenter?.openSelectAccount(with: accounts ?? []) }) .disposed(by: disposeBag) input.editTrigger .drive(onNext: { [weak self] in guard let `self` = self else { return } self.presenter?.openEditRecipient(who: $0, with: self) }) .disposed(by: disposeBag) input.deleteTrigger .drive(onNext: { [weak self] in guard let `self` = self else { return } self.presenter?.deleteRecipient(who: $0) }) .disposed(by: disposeBag) input.addTrigger .drive(onNext: { [weak self] in guard let `self` = self else { return } self.presenter?.openAddRecipient(with: self) }) .disposed(by: disposeBag) input.needEditTrigger .drive(onNext: { [weak self] in guard let `self` = self else { return } guard let recipient = self.selectedRecipient else {return} self.presenter?.openEditRecipient(who: recipient, with: self) }) .disposed(by: disposeBag) return Output( recipients: recipients, isNeedEdit: isNeedEditRecipient.asDriverOnErrorJustComplete(), isPartnerChanged: isPartnerChanged.asDriverOnErrorJustComplete(), isError: errorLinker.asDriverOnErrorJustComplete(), isProgress: progressLinker.asDriverOnErrorJustComplete() ) } } // MARK: - RecipientsViewModelInterface extension RecipientsViewModel: RecipientsViewModelInterface { func setSelectedAccount(_ account: Account) { guard let recipient = selectedRecipient else { return } presenter?.goNextStep(who: recipient, with: account) } func setRecipients(using model: [Recipient]) { recipientsLinker.onNext(model) guard let selectedID = selectedRecipientID else { return } selectedRecipient = model.filter({$0.receiverID == selectedID}).first let accounts = try? self.accountsLinker.value() presenter?.openSelectAccount(with: accounts ?? []) selectedRecipientID = nil } func setAccounts(using model: [Account]) { accountsLinker.onNext(model) } func setError(with error: Error) { errorLinker.onNext(error) } func progress(isShow: Bool) { progressLinker.onNext(isShow) } } extension RecipientsViewModel: SetupRecipientDelegate { func setupRecieient(_ viewController: SetupRecipientViewController, didSelectRecipientID: String?) { selectedRecipientID = didSelectRecipientID presenter?.fetchRecipients(isRefresh: true) } }