'use strict';

const DRY_RUN = false;

const uuid = require('node-uuid');
const Promise = require('bluebird');

const pick = (obj, attributes) => {
  const res = {};
  attributes.map(attr => {
    res[attr] = obj[attr];
  })
  return res;
}

let totalTransactions = 0;

const insert = (sequelize, table, entry) => {
  delete entry.id;
  if (DRY_RUN) {
    return console.log(`INSERT INTO "${table}":`, entry);
  }
  entry.data = entry.data &&  JSON.stringify(entry.data);
  return sequelize.query(`
    INSERT INTO "${table}" ("${Object.keys(entry).join('","')}") VALUES (:${Object.keys(entry).join(",:")})
  `, { replacements: entry });
}

const updateTransactions = (sequelize) => {

  const processTransaction = (transaction) => {

    totalTransactions++;

    transaction.TransactionGroup = uuid.v4();

    const updateOriginalTransaction = () => sequelize.query(`UPDATE "Transactions" SET "TransactionGroup"=:TransactionGroup WHERE id=:id`, { replacements: { id: transaction.id, TransactionGroup: transaction.TransactionGroup }});

    const oppositeTransaction = {
      ...transaction,
      type: (-transaction.amount > 0) ? 'CREDIT' : 'DEBIT',
      FromCollectiveId: transaction.CollectiveId,
      CollectiveId: transaction.FromCollectiveId,
      amount: -transaction.netAmountInCollectiveCurrency,
      netAmountInCollectiveCurrency: -transaction.amount,
      hostFeeInTxnCurrency: null,
      uuid: uuid.v4()
    }
    if (DRY_RUN) {
      console.log("------------------------------------")
      console.log("Processing", transaction);
    }

    // if the donation is from the host (add funds), we need to add the funds first to the Host Collective
    if (transaction.FromCollectiveId === transaction.HostCollectiveId && transaction.amount > 0 && !transaction.PaymentMethodId && !transaction.platformFeeInHostCurrency) {
      const addFundsTransaction = {
        ...transaction,
        type: 'CREDIT',
        CollectiveId: transaction.HostCollectiveId,
        HostCollectiveId: transaction.HostCollectiveId,
        FromCollectiveId: null, // money doesn't come from a collective but from an external source (Host's bank account)
        currency: transaction.currency,
        netAmountInCollectiveCurrency: transaction.amount,
        uuid: uuid.v4(),
        hostFeeInHostCurrency: null,
        platformFeeInHostCurrency: null,
        paymentProcessorFeeInHostCurrency: null
      };
      // console.log(">>> adding funds", addFundsTransaction);
      return insert(sequelize, "Transactions", addFundsTransaction)
      .then(() => insert(sequelize, "Transactions", oppositeTransaction)).then(updateOriginalTransaction);
    } else {
      return insert(sequelize, "Transactions", oppositeTransaction).then(updateOriginalTransaction);
    }
  };

  const limit = DRY_RUN ? 'LIMIT 10' : '';

  return sequelize.query(`SELECT * FROM "Transactions" ${limit}`, { type: sequelize.QueryTypes.SELECT })
  .then(rows => rows && Promise.map(rows, processTransaction, { concurrency: 10 }))
  .then(() => sequelize.query(`UPDATE "Transactions" SET type='CREDIT' WHERE type='DONATION'`))
  .then(() => sequelize.query(`UPDATE "Transactions" SET type='DEBIT' WHERE type='EXPENSE'`))
}

module.exports = {
  up: function (queryInterface, DataTypes) {
    // temporary column for binding transactions together, eventually they should all have the same OrderId if they are part of a same Order
    return queryInterface.addColumn("Transactions", "TransactionGroup", { type: DataTypes.UUID })
    .then(() => updateTransactions(queryInterface.sequelize))
    .then(() => queryInterface.renameColumn("Transactions", "txnCurrency", "hostCurrency"))
    .then(() => queryInterface.renameColumn("Transactions", "amountInTxnCurrency", "amountInHostCurrency"))
    .then(() => queryInterface.renameColumn("Transactions", "platformFeeInTxnCurrency", "platformFeeInHostCurrency"))
    .then(() => queryInterface.renameColumn("Transactions", "hostFeeInTxnCurrency", "hostFeeInHostCurrency"))
    .then(() => queryInterface.renameColumn("Transactions", "txnCurrencyFxRate", "hostCurrencyFxRate"))
    .then(() => queryInterface.renameColumn("Transactions", "paymentProcessorFeeInTxnCurrency", "paymentProcessorFeeInHostCurrency"))
    .then(() => {
        if (DRY_RUN) {
          throw new Error("Don't record as done please");
        } else {
          console.log(totalTransactions, "transactions processed");
        }
      })
  },

  down: function (queryInterface, DataTypes) {
    console.log(">>> no downgrade possible");
  }
};

@@ -2282,36 +2282,35 @@
        hostFeeIn
-Host
+Txn
 Currency: null,%0A
@@ -2322,36 +2322,35 @@
    platformFeeIn
-Host
+Txn
 Currency: null,%0A
@@ -2370,36 +2370,35 @@
 ntProcessorFeeIn
-Host
+Txn
 Currency: null%0A 

fix for migration