/*
 * Copyright 2017 Kuelap, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.mifos.individuallending.internal.service.costcomponent;

import io.mifos.individuallending.IndividualLendingPatternFactory;
import io.mifos.individuallending.api.v1.domain.product.AccountDesignators;
import io.mifos.individuallending.internal.service.DataContextOfAction;
import io.mifos.portfolio.api.v1.domain.ChargeDefinition;
import io.mifos.portfolio.api.v1.domain.Pattern;
import io.mifos.portfolio.api.v1.domain.RequiredAccountAssignment;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Myrle Krantz
 */
public interface RunningBalances {
  Map<String, BigDecimal> ACCOUNT_SIGNS = new HashMap<String, BigDecimal>() {{
    final BigDecimal negative = BigDecimal.valueOf(-1);
    final BigDecimal positive = BigDecimal.valueOf(1);

    this.put(AccountDesignators.CUSTOMER_LOAN_PRINCIPAL, negative);
    this.put(AccountDesignators.CUSTOMER_LOAN_FEES, negative);
    this.put(AccountDesignators.CUSTOMER_LOAN_INTEREST, negative);
    this.put(AccountDesignators.LOAN_FUNDS_SOURCE, negative);
    this.put(AccountDesignators.PROCESSING_FEE_INCOME, positive);
    this.put(AccountDesignators.ORIGINATION_FEE_INCOME, positive);
    this.put(AccountDesignators.DISBURSEMENT_FEE_INCOME, positive);
    this.put(AccountDesignators.INTEREST_INCOME, positive);
    this.put(AccountDesignators.INTEREST_ACCRUAL, positive);
    this.put(AccountDesignators.LATE_FEE_INCOME, positive);
    this.put(AccountDesignators.LATE_FEE_ACCRUAL, positive);
    this.put(AccountDesignators.ARREARS_ALLOWANCE, positive);
    this.put(AccountDesignators.ENTRY, positive);
  }};

  BigDecimal getAccountBalance(final String accountDesignator);

  BigDecimal getAccruedBalanceForCharge(
      final DataContextOfAction dataContextOfAction,
      final LocalDate startOfTerm,
      final ChargeDefinition chargeDefinition);

  LocalDate getStartOfTermOrThrow(final DataContextOfAction dataContextOfAction);

  default BigDecimal getLedgerBalance(final String ledgerDesignator) {
    final Pattern individualLendingPattern = IndividualLendingPatternFactory.individualLendingPattern();
    return individualLendingPattern.getAccountAssignmentsRequired().stream()
        .filter(requiredAccountAssignment -> ledgerDesignator.equals(requiredAccountAssignment.getGroup()))
        .map(RequiredAccountAssignment::getAccountDesignator)
        .map(this::getAccountBalance)
        .reduce(BigDecimal.ZERO, BigDecimal::add);
  }

  default BigDecimal getBalance(final String designator) {
    final Pattern individualLendingPattern = IndividualLendingPatternFactory.individualLendingPattern();
    if (individualLendingPattern.getAccountAssignmentGroups().contains(designator))
      return getLedgerBalance(designator);
    else
      return getAccountBalance(designator);
  }

  default BigDecimal getMaxDebit(final String accountDesignator, final BigDecimal amount) {
    if (accountDesignator.equals(AccountDesignators.ENTRY))
      return amount;

    if (ACCOUNT_SIGNS.get(accountDesignator).signum() == -1)
      return amount;
    else
      return amount.min(getBalance(accountDesignator));
  }

  default BigDecimal getMaxCredit(final String accountDesignator, final BigDecimal amount) {
    if (accountDesignator.equals(AccountDesignators.ENTRY))
      return amount; //don't guard the entry account.

    if (ACCOUNT_SIGNS.get(accountDesignator).signum() != -1)
      return amount;
    else
      return amount.min(getBalance(accountDesignator));
  }
}
