package hu.rbr.sfinapp.transaction;

import hu.rbr.sfinapp.core.service.BaseService;
import hu.rbr.sfinapp.transaction.list.TransactionListDao;
import hu.rbr.sfinapp.transaction.list.TransactionListItem;

import javax.inject.Inject;
import javax.inject.Singleton;
import javax.validation.Valid;
import java.util.List;

import static hu.rbr.sfinapp.transaction.TransactionType.*;

@Singleton
public class TransactionService extends BaseService {

    private final TransactionDao transactionDao;
    private final TransactionListDao transactionListDao;

    @Inject
    public TransactionService(TransactionDao transactionDao, TransactionListDao transactionListDao) {
        this.transactionDao = transactionDao;
        this.transactionListDao = transactionListDao;
    }

    public List<TransactionListItem> getAll() {
        List<TransactionListItem> transactions = transactionListDao.getAll();

        for (TransactionListItem transaction : transactions) {
            postProcess(transaction);
        }

        return transactions;
    }

    public Transaction get(int id) {
        Transaction transaction = transactionDao.get(id);
        return postProcess(transaction);
    }

    public Transaction create(@Valid Transaction transaction) {
        return transactionDao.create(preProcess(transaction));
    }

    public void createBatch(@Valid List<Transaction> transactions) {
        for (Transaction transaction : transactions) {
            preProcess(transaction);
        }

        transactionDao.createBatch(transactions);
    }

    public Transaction update(int id, @Valid Transaction entity) {
        return transactionDao.update(id, preProcess(entity));
    }

    public void delete(int id) {
        transactionDao.delete(id);
    }

    private Transaction preProcess(Transaction transaction) {
        correctAmountBasedOnType(transaction);
        return transaction;
    }

    private void correctAmountBasedOnType(Transaction transaction) {
        if ((transaction.type == Expense && transaction.amount > 0) ||
            (transaction.type == Income && transaction.amount < 0) ||
            (transaction.type == Transfer && transaction.amount < 0)) {

            transaction.amount *= -1;
        }
    }

    private Transaction postProcess(Transaction transaction) {
        transaction.type = calculateTransactionType(transaction);
        return transaction;
    }

    private TransactionType calculateTransactionType(Transaction transaction) {
        if (transaction.toAccountId != null) {
            return Transfer;
        }

        if (transaction.amount > 0) {
            return Income;
        }

        return Expense;
    }

}

@@ -1145,23 +1145,16 @@
         
-return 
 postProc
@@ -1167,24 +1167,52 @@
 ansaction);%0A
+        return transaction;%0A
     %7D%0A%0A    p
@@ -1262,32 +1262,65 @@
  transaction) %7B%0A
+        preProcess(transaction);%0A
         return t
@@ -1340,27 +1340,16 @@
 .create(
-preProcess(
 transact
@@ -1352,17 +1352,16 @@
 saction)
-)
 ;%0A    %7D%0A
@@ -1651,18 +1651,56 @@
 ion 
-entity
+transaction
 ) %7B%0A
+        preProcess(transaction);%0A
     
@@ -1740,26 +1740,19 @@
 id, 
-preProcess(entity)
+transaction
 );%0A 
@@ -1844,27 +1844,20 @@
 private 
-Transaction
+void
  preProc
@@ -1938,36 +1938,8 @@
 n);%0A
-        return transaction;%0A
     
@@ -2291,27 +2291,20 @@
 private 
-Transaction
+void
  postPro
@@ -2327,32 +2327,98 @@
  transaction) %7B%0A
+        if (transaction == null) %7B%0A            return;%0A        %7D%0A%0A
         transact
@@ -2471,36 +2471,8 @@
 n);%0A
-        return transaction;%0A
     

Fix NPE in TransactionService