'use strict';

angular.module('copayApp.controllers').controller('buyAmazonController',
  function($scope, $log, $timeout, $state, lodash, profileService, bwcError, gettextCatalog, configService, walletService, amazonService, ongoingProcess, platformInfo, externalLinkService, popupService) {

    var self = this;
    var network = amazonService.getEnvironment();
    var wallet;

    $scope.$on('Wallet/Changed', function(event, w) {
      if (lodash.isEmpty(w)) {
        $log.debug('No wallet provided');
        return;
      }
      wallet = w;
      $log.debug('Wallet changed: ' + w.name);
    });

    $scope.openExternalLink = function(url, target) {
      externalLinkService.open(url, target);
    };

    this.confirm = function() {
      var message = gettextCatalog.getString('Amazon.com Gift Card purchase for ${{amount}} USD', {amount: $scope.formData.fiat});
      var ok = gettextCatalog.getString('Buy');
      popupService.showConfirm(null, message, ok, null, function(res) {
        if (res) self.createTx();
      });
    };

    this.createTx = function() {
      self.errorInfo = null;

      if (lodash.isEmpty(wallet)) return;

      if (!wallet.canSign() && !wallet.isPrivKeyExternal()) {
        $log.info('No signing proposal: No private key');
        popupService.showAlert(gettextCatalog.getString('Error'), bwcError.msg('MISSING_PRIVATE_KEY'));
        return;
      }

      var dataSrc = {
        currency: 'USD',
        amount: $scope.formData.fiat,
        uuid: wallet.id
      };
      var outputs = [];
      var config = configService.getSync();
      var configWallet = config.wallet;
      var walletSettings = configWallet.settings;


      ongoingProcess.set('Processing Transaction...', true);
      $timeout(function() {
        amazonService.createBitPayInvoice(dataSrc, function(err, dataInvoice) {
          if (err) {
            ongoingProcess.set('Processing Transaction...', false);
            popupService.showAlert(gettextCatalog.getString('Error'), bwcError.msg(err));
            return;
          }

          amazonService.getBitPayInvoice(dataInvoice.invoiceId, function(err, invoice) {
            if (err) {
              ongoingProcess.set('Processing Transaction...', false);
              popupService.showAlert(gettextCatalog.getString('Error'), bwcError.msg(err));
              return;
            }

            $log.debug('Fetch PayPro Request...', invoice.paymentUrls.BIP73);

            wallet.fetchPayPro({
              payProUrl: invoice.paymentUrls.BIP73,
            }, function(err, paypro) {

              if (err) {
                ongoingProcess.set('Processing Transaction...', false);
                $log.warn('Could not fetch payment request:', err);
                var msg = err.toString();
                if (msg.match('HTTP')) {
                  msg = gettextCatalog.getString('Could not fetch payment information');
                }
                popupService.showAlert(gettextCatalog.getString('Error'), msg);
                return;
              }

              if (!paypro.verified) {
                ongoingProcess.set('Processing Transaction...', false);
                $log.warn('Failed to verify payment protocol signatures');
                popupService.showAlert(gettextCatalog.getString('Error'), gettextCatalog.getString('Payment Protocol Invalid'));
                $timeout(function() {
                  $scope.$digest();
                });
                return;
              }

              var address, comment, amount, url;

              address = paypro.toAddress;
              amount = paypro.amount;
              url = paypro.url;
              comment = 'Amazon.com Gift Card';

              outputs.push({
                'toAddress': address,
                'amount': amount,
                'message': comment
              });

              var txp = {
                toAddress: address,
                amount: amount,
                outputs: outputs,
                message: comment,
                payProUrl: url,
                excludeUnconfirmedUtxos: configWallet.spendUnconfirmed ? false : true,
                feeLevel: walletSettings.feeLevel || 'normal'
              };

              walletService.createTx(wallet, txp, function(err, createdTxp) {
                ongoingProcess.set('Processing Transaction...', false);
                if (err) {
                  popupService.showAlert(gettextCatalog.getString('Error'), bwcError.msg(err));
                  return;
                }
                walletService.publishAndSign(wallet, createdTxp, function(err, tx) {
                  if (err) {
                    ongoingProcess.set('Processing Transaction...', false);
                    popupService.showAlert(gettextCatalog.getString('Error'), bwcError.msg(err));
                    walletService.removeTx(wallet, tx, function(err) {
                      if (err) $log.debug(err);
                    });
                    $timeout(function() {
                      $scope.$digest();
                    });
                    return;
                  }
                  var count = 0;
                  ongoingProcess.set('Processing Transaction...', true);

                  dataSrc.accessKey = dataInvoice.accessKey;
                  dataSrc.invoiceId = invoice.id;
                  dataSrc.invoiceUrl = invoice.url;
                  dataSrc.invoiceTime = invoice.invoiceTime;

                  self.debounceCreate(count, dataSrc);
                });
              });
            });
          });
        });
      }, 100);
    };

    self.debounceCreate = lodash.throttle(function(count, dataSrc) {
      self.debounceCreateGiftCard(count, dataSrc);
    }, 8000, {
      'leading': true
    });

    self.debounceCreateGiftCard = function(count, dataSrc) {

      amazonService.createGiftCard(dataSrc, function(err, giftCard) {
        $log.debug("creating gift card " + count);
        if (err) {
          giftCard = {};
          giftCard.status = 'FAILURE';
          ongoingProcess.set('Processing Transaction...', false);
          popupService.showAlert(gettextCatalog.getString('Error'), bwcError.msg(err));
          self.errorInfo = dataSrc;
          $timeout(function() {
            $scope.$digest();
          });
        }

        if (giftCard.status == 'PENDING' && count < 3) {
          $log.debug("pending gift card not available yet");
          self.debounceCreate(count + 1, dataSrc, dataSrc);
          return;
        }

        var now = moment().unix() * 1000;

        var newData = giftCard;
        newData['invoiceId'] = dataSrc.invoiceId;
        newData['accessKey'] = dataSrc.accessKey;
        newData['invoiceUrl'] = dataSrc.invoiceUrl;
        newData['amount'] = dataSrc.amount;
        newData['date'] = dataSrc.invoiceTime || now;
        newData['uuid'] = dataSrc.uuid;

        if (newData.status == 'expired') {
          amazonService.savePendingGiftCard(newData, {
            remove: true
          }, function(err) {
            return;
          });
        }

        amazonService.savePendingGiftCard(newData, null, function(err) {
          ongoingProcess.set('Processing Transaction...', false);
          $log.debug("Saving new gift card with status: " + newData.status);

          self.giftCard = newData;
          if (newData.status == 'PENDING') $state.transitionTo('tabs.giftcards.amazon');
          $timeout(function() {
            $scope.$digest();
          });
        });
      });
    };

    $scope.$on("$ionicView.enter", function(event, data){
      $scope.formData = { fiat: null };
      $scope.wallets = profileService.getWallets({
        network: network,
        onlyComplete: true
      });
    });

  });
