/**
 * Broadcast updates to client when the model changes
 */

'use strict';

var Q = require('q');

var Wallet = require('./../wallet/wallet.model');
var BankAccount = require('../bankaccount/bankaccount.model');
var CreateWallet = require('./../create_wallet/create_wallet.socket');
var Utils = require('./../../utils/utils');

var debug = require('debug')('MakeTransfer');

function makeTransfer(fromEmail, toEmail, amount) {
    var promiseFindSenderWallet = Wallet.findByOwnerEmail(fromEmail);
    var promiseFindRecvWallet = Wallet.findByOwnerEmail(toEmail);

    var promiseFindIssuingBank = CreateWallet.getBankForUser(fromEmail);

    var promiseFindSenderBankAccount = BankAccount.findOneQ({ email: fromEmail });

    return Q.allSettled([promiseFindSenderWallet, promiseFindRecvWallet, promiseFindIssuingBank, promiseFindSenderBankAccount])
        .spread(function (senderWalletPromise, recvWalletPromise, findIssuingBankPromise, senderBankPromise) {
            var deferred = Q.defer();

            var senderWallet = senderWalletPromise.value;
            var recvWallet = recvWalletPromise.value;
            var senderBank = senderBankPromise.value;
            var findIssuingBank = findIssuingBankPromise.value;

            function buildMissingError(errorMessage) {
                errorMessage = errorMessage || 'missing account';
                var result = {
                    fromEmail: fromEmail,
                    toEmail: toEmail,
                    amount: amount,
                    issuer: issuingAddress,
                    status: 'error',
                    message: errorMessage
                };

                Utils.getEventEmitter().emit('post:make_transfer', result);
                deferred.resolve(result);
            }

            var issuingAddress;

            // If the sender was a bank admin, get its wallet from bankaccounts
            if (!senderWallet && senderBank) {
                senderWallet = senderBank.hotWallet;
            }

            // Not sure why these are arrays sometimes
            if (senderWallet && senderWallet.constructor === Array) {
                senderWallet = senderWallet[0];
            }
            if (recvWallet && recvWallet.constructor === Array) {
                recvWallet = recvWallet[0];
            }

            if (!senderWallet || !recvWallet) {
                // At least a wallet is missing, it's a bust
                buildMissingError();
                return deferred.promise;
            }

            if (!senderBank) {
                if (!findIssuingBank || findIssuingBank.status === 'error' || !findIssuingBank.bank ||
                  !findIssuingBank.bank.hotWallet || !findIssuingBank.bank.hotWallet.address) {

                    buildMissingError('issuing bank not resolved');

                    return deferred.promise;
                } else {
                    issuingAddress = findIssuingBank.bank.hotWallet.address;
                }
            } else {
                // Sender is a bank
                issuingAddress = senderBank.hotWallet.address;
            }

            makeTransferWithRipple(senderWallet, recvWallet, issuingAddress, amount).then(function(transaction){
              Utils.getEventEmitter().emit('post:make_transfer', {
                fromEmail: fromEmail,
                toEmail: toEmail,
                amount: amount,
                issuer: issuingAddress,
                status: 'success'
              });
              deferred.resolve({ status: 'success', transaction: transaction });
            }, function(err){
              var errorMessage = 'Ripple error. Cannot transfer from ' + fromEmail + ' to ' + toEmail + ' ' + amount + ' €!';
                Utils.getEventEmitter().emit('post:make_transfer', {
                fromEmail: fromEmail,
                toEmail: toEmail,
                amount: amount,
                issuer: issuingAddress,
                message: errorMessage,
                status: 'ripple error'
              });
              deferred.reject(err);
            });

            return deferred.promise;
        });
}

function makeTransferWithRipple(senderWallet, recvWallet, dstIssuer, amount, srcIssuer) {
  debug('makeTransferWithRipple', senderWallet, recvWallet, dstIssuer, amount, srcIssuer);
  var deferred = Q.defer();

  dstIssuer = dstIssuer || senderWallet.address; // Normal issuer, for single gateway transactions
  // Can't assume anything about source issuer!

  Utils.getNewConnectedRemote(senderWallet.address, senderWallet.secret).then(function (remote) {
    var transaction = remote.createTransaction('Payment', {
      account: senderWallet.address,
      destination: recvWallet.address,
      amount: amount + '/EUR/' + dstIssuer,
    });

    // Append it if you got it
    if (srcIssuer) {
           var maxValue = amount.toString(); // Send all; original code from ripple-rest is:
                               // new BigNumber(payment.source_amount.value).plus(payment.source_slippage || 0).toString();
           transaction.sendMax({
              value: maxValue,
              currency: 'EUR',      // EUR foreveeer
              issuer: srcIssuer,    // Gotcha!
           });
    }

    transaction.submit(function (err, res) {
      if (err) {
        deferred.reject(err);
      }
      if (res) {
        deferred.resolve({ status: 'success', transaction: transaction });
      }
    });

  });
  return deferred.promise;
}

exports.makeTransfer = makeTransfer;
exports.makeTransferWithRipple = makeTransferWithRipple;

exports.register = function (socket) {
    Utils.getEventEmitter().on('post:make_transfer', function (data) {
        socket.emit('post:make_transfer', data);
    });

    Utils.getEventEmitter().on('make_transfer', function (data) {
        makeTransfer(data.fromEmail, data.toEmail, data.amount);
    });

    socket.on('make_transfer', function (data) {
        makeTransfer(data.fromEmail, data.toEmail, data.amount);
    });
};

@@ -590,16 +590,17 @@
 ingBank 
+ 
 = Create
@@ -625,32 +625,156 @@
 ser(fromEmail);%0A
+    var promiseFindDestUserBank = CreateWallet.getBankForUser(toEmail); // If the destination user is from another bank%0A    
 %0A    var promise
@@ -967,16 +967,41 @@
 kAccount
+, promiseFindDestUserBank
 %5D)%0A     
@@ -1102,16 +1102,37 @@
 kPromise
+, destUserBankPromise
 ) %7B%0A    
@@ -1396,16 +1396,129 @@
 .value;%0A
+            var destUserBank    = destUserBankPromise.value ? destUserBankPromise.value.bank : null;%0A            
 %0A       
@@ -2084,16 +2084,27 @@
 gAddress
+, srcIssuer
 ;%0A%0A     
@@ -3398,32 +3398,376 @@
 ;%0A            %7D%0A
+            %0A            if (destUserBank && destUserBank.hotWallet.address !== issuingAddress) %7B%0A                // Is the destination user from another bank?%0A                srcIssuer = issuingAddress;%0A                issuingAddress = destUserBank.hotWallet.address;%0A                // XXX fix non-intuive var names%0A            %7D%0A            
 %0A            mak
@@ -3834,16 +3834,27 @@
 , amount
+, srcIssuer
 ).then(f

yes! fixed inter bank transfers