/*
 * Copyright 2017 The Mifos Initiative.
 *
 * 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.portfolio.service.internal.mapper;

import io.mifos.core.api.util.UserContextHolder;
import io.mifos.core.lang.DateConverter;
import io.mifos.portfolio.api.v1.domain.*;
import io.mifos.portfolio.service.internal.repository.ProductAccountAssignmentEntity;
import io.mifos.portfolio.service.internal.repository.ProductEntity;
import io.mifos.portfolio.service.internal.util.AccountingAdapter;

import java.math.BigDecimal;
import java.time.Clock;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author Myrle Krantz
 */
public class ProductMapper {
  public static Product map(final ProductEntity productEntity) {
    final Product product = new Product();
    product.setIdentifier(productEntity.getIdentifier());
    product.setName(productEntity.getName());
    product.setTermRange(
            new TermRange(productEntity.getTermRangeTemporalUnit(),
                    productEntity.getTermRangeMaximum()));
    product.setBalanceRange(
            new BalanceRange(productEntity.getBalanceRangeMinimum().setScale(productEntity.getMinorCurrencyUnitDigits(), BigDecimal.ROUND_HALF_EVEN), productEntity.getBalanceRangeMaximum().setScale(productEntity.getMinorCurrencyUnitDigits(), BigDecimal.ROUND_HALF_EVEN)));
    product.setInterestRange(
            new InterestRange(productEntity.getInterestRangeMinimum(), productEntity.getInterestRangeMaximum()));
    product.setInterestBasis(productEntity.getInterestBasis());
    product.setPatternPackage(productEntity.getPatternPackage());
    product.setDescription(productEntity.getDescription());
    product.setCurrencyCode(productEntity.getCurrencyCode());
    product.setMinorCurrencyUnitDigits(productEntity.getMinorCurrencyUnitDigits());
    product.setAccountAssignments(productEntity.getAccountAssignments()
            .stream().map(ProductMapper::mapAccountAssignmentEntity).collect(Collectors.toSet()));
    product.setParameters(productEntity.getParameters());
    product.setCreatedBy(productEntity.getCreatedBy());
    product.setCreatedOn(DateConverter.toIsoString(productEntity.getCreatedOn()));
    product.setLastModifiedBy(productEntity.getLastModifiedBy());
    product.setLastModifiedOn(DateConverter.toIsoString(productEntity.getLastModifiedOn()));
    product.setEnabled(productEntity.getEnabled());

    return product;
  }

  public static ProductEntity map(final Product product, boolean enabled)
  {
    final ProductEntity ret = new ProductEntity();

    ret.setIdentifier(product.getIdentifier());
    ret.setName(product.getName());
    ret.setTermRangeTemporalUnit(product.getTermRange().getTemporalUnit());
    ret.setTermRangeMinimum(0);
    ret.setTermRangeMaximum(product.getTermRange().getMaximum());
    ret.setBalanceRangeMinimum(product.getBalanceRange().getMinimum());
    ret.setBalanceRangeMaximum(product.getBalanceRange().getMaximum());
    ret.setInterestRangeMinimum(product.getInterestRange().getMinimum());
    ret.setInterestRangeMaximum(product.getInterestRange().getMaximum());
    ret.setInterestBasis(product.getInterestBasis());
    ret.setPatternPackage(product.getPatternPackage());
    ret.setDescription(product.getDescription());
    ret.setCurrencyCode(product.getCurrencyCode());
    ret.setMinorCurrencyUnitDigits(product.getMinorCurrencyUnitDigits());
    ret.setAccountAssignments(product.getAccountAssignments().stream()
            .map(x -> ProductMapper.map(x, ret))
            .collect(Collectors.toSet()));
    ret.setParameters(product.getParameters());
    ret.setEnabled(enabled);

    final LocalDateTime time = LocalDateTime.now(Clock.systemUTC());
    final String user = UserContextHolder.checkedGetUser();
    ret.setCreatedOn(time);
    ret.setCreatedBy(user);
    ret.setLastModifiedOn(time);
    ret.setLastModifiedBy(user);

    return ret;
  }

  private static ProductAccountAssignmentEntity map (final AccountAssignment accountAssignment,
                                                     final ProductEntity productEntity)
  {
    final ProductAccountAssignmentEntity ret = new ProductAccountAssignmentEntity();
    ret.setProduct(productEntity);
    ret.setDesignator(accountAssignment.getDesignator());
    if (accountAssignment.getAccountIdentifier() != null) {
      ret.setIdentifier(accountAssignment.getAccountIdentifier());
      ret.setType(AccountingAdapter.IdentifierType.ACCOUNT);
    }
    else if (accountAssignment.getLedgerIdentifier() != null) {
      ret.setIdentifier(accountAssignment.getLedgerIdentifier());
      ret.setType(AccountingAdapter.IdentifierType.LEDGER);
    }
    return ret;
  }

  public static AccountAssignment mapAccountAssignmentEntity (final ProductAccountAssignmentEntity productAccountAssignmentEntity)
  {
    final AccountAssignment ret = new AccountAssignment();
    ret.setDesignator(productAccountAssignmentEntity.getDesignator());
    if (productAccountAssignmentEntity.getType() == AccountingAdapter.IdentifierType.ACCOUNT) {
      ret.setAccountIdentifier(productAccountAssignmentEntity.getIdentifier());
    }
    else if (productAccountAssignmentEntity.getType() == AccountingAdapter.IdentifierType.LEDGER) {
      ret.setLedgerIdentifier(productAccountAssignmentEntity.getIdentifier());
    }
    return ret;
  }

  public static List<Product> map(final List<ProductEntity> productEntities) {
    return productEntities.stream().map(ProductMapper::map).collect(Collectors.toList());
  }

  public static ProductEntity mapOverOldEntity(final Product instance, final ProductEntity oldEntity) {
    final ProductEntity newEntity = map(instance, false);

    newEntity.setId(oldEntity.getId());
    newEntity.setCreatedBy(oldEntity.getCreatedBy());
    newEntity.setCreatedOn(oldEntity.getCreatedOn());

    final Set<ProductAccountAssignmentEntity> oldAccountAssignmentEntities = oldEntity.getAccountAssignments();
    final Map<String, ProductAccountAssignmentEntity> accountAssignmentsMap
            = oldAccountAssignmentEntities.stream()
            .collect(Collectors.toMap(ProductAccountAssignmentEntity::getDesignator, x -> x));

    final Set<AccountAssignment> newAccountAssignments = instance.getAccountAssignments();
    final Set<ProductAccountAssignmentEntity> newAccountAssignmentEntities =
    newAccountAssignments.stream().map(x -> {
      final ProductAccountAssignmentEntity newAccountAssignmentEntity = ProductMapper.map(x, newEntity);
      final ProductAccountAssignmentEntity oldAccountAssignmentEntity = accountAssignmentsMap.get(x.getDesignator());
      if (oldAccountAssignmentEntity != null) newAccountAssignmentEntity.setId(oldAccountAssignmentEntity.getId());

      return newAccountAssignmentEntity;
    }).collect(Collectors.toSet());
    newEntity.setAccountAssignments(newAccountAssignmentEntities);

    newEntity.setChargeDefinitions(oldEntity.getChargeDefinitions());
    newEntity.setTaskDefinitions(oldEntity.getTaskDefinitions());


    return newEntity;
  }
}
