// // P2PLockedFundsController.swift // Wallet // // Created by Saveliy Stavitsky on 7/9/21. // Copyright © 2021 AM. All rights reserved. // import UIKit import WalletFoundation class P2PLockedFundsController: UITableViewController { let service = P2PMainLockedFundsService() override func viewDidLoad() { super.viewDidLoad() navigationItem.title = L10n.P2p.Main.LockedFunds.headerTitle navigationItem.leftBarButtonItem = .pop(self) tableView.showsVerticalScrollIndicator = false tableView.separatorStyle = .none tableView.allowsSelection = false tableView.backgroundColor = Asset.gypsum.color tableView.register(cell: DealTableViewCell.self) tableView.register(cell: P2PBalanceTableViewCell.self) tableView.register(cell: P2PCellOrder.self) service.didUpdate = { [weak self] in self?.update() } service.combineList() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) Accounts().isLocked = true self.navigationController >>- { $0.navigationBar.isTranslucent = false $0.navigationBar.backgroundColor = Asset.snow.color $0.setNavigationBarHidden(false, animated: true) } } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) Accounts().isLocked = false } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() } private func update() { Loader.hide() tableView.reloadData() } func edit(order: P2POrder) { let ctrl = StoryboardScene.P2P.order.instantiate() let token = P2P.Service.tokens.first(where: { $0.symbol == order.symbol })! ctrl.service = .init(kind: order.kind, contentType: order.contentType, token: token, order: P2POrder(value: order)) ctrl.service.card = Cards.shared.collection .first(where: { $0.number == order.cardNumber ?? "" }) ?? Cards.shared.default ctrl.service.paymentSystem = order.paymentSystem.map({ (id: $0.id, title: $0.name, description: "") }) ctrl.service.tokenGet = order.currency.map({ (id: $0.id, title: $0.name, description: $0.descriptn ?? "") }) ctrl.service.blockchain = order.blockchain.map({ (id: $0.id, title: $0.name, description: $0.descriptn ?? "") }) ctrl.service.rateToken1 = order.rateIsReversed ? order.rate.decimalValue.toReadebleString(precisionMax: 12) : "1" ctrl.service.rateToken2 = order.rateIsReversed ? "1" : order.rate.decimalValue.toReadebleString(precisionMax: 12) ctrl.service.amount = order.volume.decimalValue.toReadebleString(precisionMax: 2) ctrl.service.limitMin = order.min.decimalValue.toReadebleString(precisionMax: 2) ctrl.service.limitMax = order.max.decimalValue.toReadebleString(precisionMax: 2) ctrl.service.link = order.paymentUrl ?? "" ctrl.service.vcardNumber = order.cardNumber ?? "" ctrl.service.vcardName = order.cardName ?? "" ctrl.service.vcardExpiration = order.cardDate ?? "" ctrl.service.vcardCVV = order.cvv ?? "" ctrl.service.country = order.country.map({ (id: $0.id, title: $0.name, description: "") }) ctrl.service.city = order.city.map({ (id: $0.id, title: $0.name, description: "") }) ctrl.service.bank = order.banks.map({ (id: $0.id, title: $0.name, description: "") }) ctrl.service.account = order.walletNumber ?? order.walletAddress ?? "" ctrl.service.memo = order.memo ?? "" self.mainController.content.push(ctrl, animated: true) } } extension P2PLockedFundsController { override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { service.items.count } //swiftlint:disable:next function_body_length override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard indexPath.row < service.items.count else { return UITableViewCell() } switch service.items[indexPath.row] { case let deal as P2PDeal: let cell = tableView.dequeueReusableCell(DealTableViewCell.self, indexPath: indexPath) cell.p2pDealView.tableView = tableView cell.p2pDealView.completionTopSection = { [weak self] in let tabIndex = deal.seller == Accounts().current?.name ? 2 : 3 self?.mainController.content.selectedIndex = tabIndex ((self?.mainController.content.viewControllers?[tabIndex] as? UINavigationController)?.viewControllers.first as? P2PControllerDashboard)?.service.token = Wallet.Service.Tokens.shared.balances.collection.first(where: { $0.isCashContract && $0.symbol == deal.symbol }) } // guard indexPath.row < service.deals.dealsToShow.count else { return cell } // let deal = service.deals.dealsToShow[indexPath.row] cell.p2pDealView.setup(model: deal, lockedFunds: true) { [weak self] action in guard let self else { return } switch action { case .complete: if deal.isExpired && deal.seller == Accounts().current?.name && deal.status != .dispute { AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show() self.service.service.complete(privateKey: $0, deal: deal) { (error) in Loader.hide() Alert.notify(error) } } } else if deal.isExpired && deal.buyer == Accounts().current?.name && deal.status != .dispute { Popup.show( title: L10n.P2p.Dashboard.Deal.Confirm.title, views: [ .label( text: L10n.P2p.Dashboard.Deal.Confirm.Complete.Text.expired .attributed(style: .regular, size: 14, color: Asset.textCoal.color), numberOfLines: 0 ), .warning(text: L10n.P2p.Dashboard.Deal.Confirm.Complete.Warning.expired), .field( title: L10n.P2p.Dashboard.Deal.Confirm.Complete.Amount.expired, text: (deal.volume.decimalValue + deal.insurance.decimalValue).toString(max: deal.precision, symbol: deal.symbol) ), .field( title: L10n.P2p.Dashboard.Deal.Confirm.Complete.Insurance.expired, text: deal.insurance.decimalValue.toString(max: deal.precision, symbol: deal.symbol) ) ], submit: L10n.P2p.Dashboard.Deal.Confirm.submit, in: self ) { ctrl in AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show(in: ctrl) self.service.service.complete(privateKey: $0, deal: deal) { (error) in Loader.hide(in: ctrl) ctrl.dismiss(animated: true) Alert.notify(error) } } } } else { Popup.show( title: L10n.P2p.Dashboard.Deal.Confirm.title, views: [ .label( text: L10n.P2p.Dashboard.Deal.Confirm.Complete.text(deal.volume.decimalValue.toString(max: deal.precision, symbol: deal.symbol)) .attributed(style: .regular, size: 14, color: Asset.textCoal.color), numberOfLines: 0 ), .warning(text: L10n.P2p.Dashboard.Deal.Confirm.Complete.warning), .field( title: L10n.P2p.Dashboard.Deal.Confirm.Complete.amount, text: deal.volume.decimalValue.toString(max: deal.precision, symbol: deal.symbol) ), .field( title: L10n.P2p.Dashboard.Deal.Confirm.Complete.insurance, text: deal.insurance.decimalValue.toString(max: deal.precision, symbol: deal.symbol) ) ], submit: L10n.P2p.Dashboard.Deal.Confirm.submit, in: self ) { ctrl in AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show(in: ctrl) self.service.service.complete(privateKey: $0, deal: deal) { (error) in Loader.hide(in: ctrl) ctrl.dismiss(animated: true) Alert.notify(error) } } } } case .dispute: Popup.show( title: L10n.P2p.Dashboard.Deal.Confirm.title, views: [ .label( text: L10n.P2p.Dashboard.Deal.Confirm.Dispute.text1.attributed(style: .regular, size: 14, color: Asset.textCoal.color), numberOfLines: 0 ), .warning(text: L10n.P2p.Dashboard.Deal.Confirm.Dispute.warning), .label( text: L10n.P2p.Dashboard.Deal.Confirm.Dispute.text2.attributed(style: .regular, size: 14, color: Asset.textCoal.color), numberOfLines: 0 ) ], submit: L10n.P2p.Dashboard.Deal.Confirm.submit, in: self ) { ctrl in AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show(in: ctrl) self.service.service.dispute(privateKey: $0, deal: deal) { (error) in Loader.hide(in: ctrl) Alert.notify(error, dismiss: ctrl) } } } case .cancel: if deal.seller == Accounts().current?.name || !deal.isExpired { Popup.show( title: L10n.P2p.Dashboard.Deal.Confirm.title, views: [ .label( text: L10n.P2p.Dashboard.Deal.Confirm.Cancel.text("100").attributed(style: .regular, size: 14, color: Asset.textCoal.color), numberOfLines: 0 ), .warning(text: L10n.P2p.Dashboard.Deal.Confirm.Cancel.warning), .field( title: L10n.P2p.Dashboard.Deal.Confirm.Cancel.insurance, text: deal.insurance.decimalValue.toString(max: deal.precision, symbol: deal.symbol) ) ], submit: L10n.P2p.Dashboard.Deal.Confirm.submit, in: self ) { ctrl in AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show(in: ctrl) self.service.service.cancel(privateKey: $0, deal: deal) { (error) in Loader.hide(in: ctrl) Alert.notify(error, dismiss: ctrl) } } } } else { Popup.show( title: L10n.P2p.Dashboard.Deal.Confirm.title, views: [ .label( text: L10n.P2p.Dashboard.Deal.Confirm.Cancel.text("100").attributed(style: .regular, size: 14, color: Asset.textCoal.color), numberOfLines: 0 ), .warning(text: L10n.P2p.Dashboard.Deal.Confirm.Cancel.warning), .field( title: L10n.P2p.Dashboard.Deal.Confirm.Cancel.insurance, text: deal.insurance.decimalValue.toString(max: deal.precision, symbol: deal.symbol) ) ], submit: L10n.P2p.Dashboard.Deal.Confirm.submit, in: self ) { ctrl in AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show(in: ctrl) self.service.service.cancel(privateKey: $0, deal: deal) { (error) in Loader.hide(in: ctrl) Alert.notify(error, dismiss: ctrl) } } } } case .withdraw: AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show() self.service.service.withdraw(privateKey: $0, deal: deal) { (error) in Loader.hide() Alert.notify(error) } } case .pay: Loader.show() self.service.service.pay(deal: deal) { (error) in Loader.hide() Alert.notify(error) } case .chat: break } } return cell case let order as P2POrder: let cell = tableView.dequeueReusableCell(P2PCellOrder.self, indexPath: indexPath) cell.tableView = tableView cell.completionTopSection = { [weak self] in let tabIndex = order.kind == .buy ? 3 : 2 self?.mainController.content.selectedIndex = tabIndex ((self?.mainController.content.viewControllers?[tabIndex] as? UINavigationController)?.viewControllers.first as? P2PControllerDashboard)?.service.token = Wallet.Service.Tokens.shared.balances.collection.first(where: { $0.isCashContract && $0.symbol == order.symbol }) } // guard indexPath.row < service.orders.collection.count else { return cell } // let order = service.orders.collection[indexPath.row] cell.setup(model: order, lockedFunds: true) { [weak self] action in guard let self else { return } switch action { case .buy, .sell: break case .pause: AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show() order.pause(privateKey: $0) { (error) in Loader.hide() Alert.notify(error) } } case .resume: AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show() order.resume(privateKey: $0) { (error) in Loader.hide() Alert.notify(error) } } case .cancel: AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show() order.cancel(privateKey: $0) { (error) in Loader.hide() Alert.notify(error) } } case .chat: break case .more: let ctrl = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) ctrl.addAction(.init(title: L10n.P2p.Dashboard.Order.Action.moreEdit, style: .default) { [weak self] _ in guard let self = self else { return } // if order.status == .inactive { // edit(order: order) // return // } Popup.show( title: L10n.P2p.Dashboard.Order.Action.MoreEdit.title, views: [ .label( text: (order.kind == .buy ? L10n.P2p.Dashboard.Order.Action.MoreEdit.descriptionBuy : L10n.P2p.Dashboard.Order.Action.MoreEdit.descriptionSell) .attributed(style: .regular, size: 14, color: Asset.textCoal.color), numberOfLines: 0 ), .warning(text: L10n.P2p.Dashboard.Order.Action.MoreEdit.warning), ], submit: order.status == .inactive ? L10n.P2p.Dashboard.Order.Action.MoreEdit.edit : L10n.P2p.Dashboard.Order.Action.MoreEdit.stopAndEdit, cancel: L10n.Common.Button.cancel, cancelStyle: .tertiary, cancelSize: .small, in: self ) { [weak self] ctrl in guard let self = self else { Popup.hide() return } if order.status == .active { AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show() order.pause(privateKey: $0) { (error) in Loader.hide() Popup.hide() Alert.notify(error) self.edit(order: order) } } } else { Popup.hide() self.edit(order: order) } } }) ctrl.addAction(.init(title: L10n.P2p.Dashboard.Order.Action.moreCancel, style: .default) { [weak self] _ in guard let self = self else { return } Popup.show( title: L10n.Common.Title.confirmation, views: [ .label( text: (order.kind == .buy ? L10n.P2p.Dashboard.Order.Action.MoreCancel.descriptionBuy : L10n.P2p.Dashboard.Order.Action.MoreCancel.descriptionSell) .attributed(style: .regular, size: 14, color: Asset.textCoal.color), numberOfLines: 0 ), .field( title: L10n.P2p.Dashboard.Order.Action.MoreCancel.get, text: (order.kind == .buy ? order.insurance.decimalValue : order.volume.decimalValue).toReadebleString(precisionMax: order.precision, symbol: order.symbol) ), .field( title: L10n.P2p.Dashboard.Order.Action.MoreCancel.deposit, text: (order.volume.decimalValue * 0.1).toReadebleString(precisionMax: order.precision, symbol: order.symbol) ) ].dropLast(order.kind == .buy ? 1 : 0), submit: L10n.Common.Button.confirm, in: self ) { ctrl in AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show() order.cancel(privateKey: $0) { (error) in Loader.hide() Popup.hide() Alert.notify(error) } } } }) ctrl.addAction(.init(title: L10n.Common.Button.cancel, style: .cancel, handler: nil)) self.present(ctrl, animated: true) } } return cell case let balance as P2PBalance: let cell = tableView.dequeueReusableCell(P2PBalanceTableViewCell.self, indexPath: indexPath) cell.setup(model: balance) { [weak self] action in self?.withrawBalance(symbol: balance.symbol, precision: balance.precision) } return cell default: return UITableViewCell() } } } extension P2PLockedFundsController { private func withrawBalance(symbol: String, precision: Int) { AccountViewAuthorize.showGetPrivateKey(in: self) { Loader.show() self.service.p2pBalancesService.withdraw(privateKey: $0, symbol: symbol, precision: precision) { (error) in Loader.hide() Alert.notify(error, pop: self) } } } }