/*
 * 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.deposit.service.internal.command.handler;

import io.mifos.accounting.api.v1.domain.Account;
import io.mifos.core.api.util.UserContextHolder;
import io.mifos.core.command.annotation.Aggregate;
import io.mifos.core.command.annotation.CommandHandler;
import io.mifos.core.command.annotation.EventEmitter;
import io.mifos.core.lang.ServiceException;
import io.mifos.deposit.api.v1.EventConstants;
import io.mifos.deposit.api.v1.instance.domain.ProductInstance;
import io.mifos.deposit.service.ServiceConstants;
import io.mifos.deposit.service.internal.command.ActivateProductInstanceCommand;
import io.mifos.deposit.service.internal.command.CloseProductInstanceCommand;
import io.mifos.deposit.service.internal.command.CreateProductInstanceCommand;
import io.mifos.deposit.service.internal.command.TransactionProcessedCommand;
import io.mifos.deposit.service.internal.command.UpdateProductInstanceCommand;
import io.mifos.deposit.service.internal.mapper.ProductInstanceMapper;
import io.mifos.deposit.service.internal.repository.ProductDefinitionEntity;
import io.mifos.deposit.service.internal.repository.ProductDefinitionRepository;
import io.mifos.deposit.service.internal.repository.ProductInstanceEntity;
import io.mifos.deposit.service.internal.repository.ProductInstanceRepository;
import io.mifos.deposit.service.internal.service.helper.AccountingService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.annotation.Transactional;

import java.time.Clock;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Aggregate
public class ProductInstanceAggregate {

  private final Logger logger;
  private final ProductInstanceRepository productInstanceRepository;
  private final ProductDefinitionRepository productDefinitionRepository;
  private final AccountingService accountingService;

  @Autowired
  public ProductInstanceAggregate(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
                                  final ProductInstanceRepository productInstanceRepository,
                                  final ProductDefinitionRepository productDefinitionRepository,
                                  final AccountingService accountingService) {
    this.logger = logger;
    this.productInstanceRepository = productInstanceRepository;
    this.productDefinitionRepository = productDefinitionRepository;
    this.accountingService = accountingService;
  }

  @CommandHandler
  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.POST_PRODUCT_INSTANCE)
  @Transactional
  public String createProductInstance(final CreateProductInstanceCommand createProductInstanceCommand) {
    final ProductInstance productInstance = createProductInstanceCommand.productInstance();

    final ProductInstanceEntity productInstanceEntity =
        ProductInstanceMapper.map(productInstance, this.productDefinitionRepository);

    final Optional<ProductDefinitionEntity> optionalProductDefinition =
        productDefinitionRepository.findByIdentifier(productInstance.getProductIdentifier());

    optionalProductDefinition.ifPresent(productDefinitionEntity -> {

      final List<ProductInstanceEntity> currentProductInstances =
          this.productInstanceRepository.findByCustomerIdentifier(productInstance.getCustomerIdentifier());

      final int accountSuffix = currentProductInstances.size() + 1;
      final String accountNumber =
          productInstance.getCustomerIdentifier() +
              "." + productDefinitionEntity.getEquityLedgerIdentifier() +
              "." + String.format("%05d", accountSuffix);

      productInstanceEntity.setAccountIdentifier(accountNumber);

      this.accountingService.createAccount(productDefinitionEntity.getEquityLedgerIdentifier(),
          productDefinitionEntity.getName(), productInstanceEntity.getCustomerIdentifier(),
          accountNumber, productInstance.getAlternativeAccountNumber(),
          productInstance.getBalance());
    });

    productInstanceEntity.setCreatedBy(UserContextHolder.checkedGetUser());
    productInstanceEntity.setCreatedOn(LocalDateTime.now(Clock.systemUTC()));
    productInstanceEntity.setState("PENDING");

    this.productInstanceRepository.save(productInstanceEntity);
    return productInstance.getCustomerIdentifier();
  }

  @Transactional
  @CommandHandler
  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.ACTIVATE_PRODUCT_INSTANCE)
  public String process(final ActivateProductInstanceCommand activateProductInstanceCommand) {
    final String accountIdentifier = activateProductInstanceCommand.identifier();
    final Optional<ProductInstanceEntity> optionalProductInstance =
        this.productInstanceRepository.findByAccountIdentifier(accountIdentifier);

    if (optionalProductInstance.isPresent()) {
      final ProductInstanceEntity productInstanceEntity = optionalProductInstance.get();
      productInstanceEntity.setState("ACTIVE");
      if (productInstanceEntity.getOpenedOn() == null) {
        productInstanceEntity.setOpenedOn(LocalDate.now(Clock.systemUTC()));
      }
      productInstanceEntity.setLastModifiedBy(UserContextHolder.checkedGetUser());
      productInstanceEntity.setLastModifiedOn(LocalDateTime.now(Clock.systemUTC()));
      this.productInstanceRepository.save(productInstanceEntity);

      return accountIdentifier;
    } else {
      this.logger.warn("Product instance for account {} not found.", accountIdentifier);
    }

    return null;
  }

  @Transactional
  @CommandHandler
  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.CLOSE_PRODUCT_INSTANCE)
  public String process(final CloseProductInstanceCommand closeProductInstanceCommand) {
    final String accountIdentifier = closeProductInstanceCommand.identifier();
    final Optional<ProductInstanceEntity> optionalProductInstance =
        this.productInstanceRepository.findByAccountIdentifier(accountIdentifier);

    if (optionalProductInstance.isPresent()) {
      final ProductInstanceEntity productInstanceEntity = optionalProductInstance.get();
      productInstanceEntity.setState("CLOSED");
      productInstanceEntity.setLastModifiedBy(UserContextHolder.checkedGetUser());
      productInstanceEntity.setLastModifiedOn(LocalDateTime.now(Clock.systemUTC()));
      this.productInstanceRepository.save(productInstanceEntity);

      return accountIdentifier;
    } else {
      this.logger.warn("Product instance for account {} not found.", accountIdentifier);
    }

    return null;
  }

  @Transactional
  @CommandHandler
  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_PRODUCT_INSTANCE)
  public String process(final UpdateProductInstanceCommand updateProductInstanceCommand) {
    final ProductInstance productInstance = updateProductInstanceCommand.productInstance();
    final Optional<ProductInstanceEntity> optionalProductInstance =
        this.productInstanceRepository.findByAccountIdentifier(productInstance.getAccountIdentifier());

    if (optionalProductInstance.isPresent()) {
      final ProductInstanceEntity productInstanceEntity = optionalProductInstance.get();

      if (this.hasChanged(productInstance, productInstanceEntity)) {
        final Account account = this.accountingService.findAccount(productInstanceEntity.getAccountIdentifier());
        account.setSignatureAuthorities(productInstance.getBeneficiaries());
        this.accountingService.updateAccount(account);

        productInstanceEntity.setBeneficiaries(
            productInstance.getBeneficiaries().stream().collect(Collectors.joining(",")));
        productInstanceEntity.setLastModifiedBy(UserContextHolder.checkedGetUser());
        productInstanceEntity.setLastModifiedOn(LocalDateTime.now(Clock.systemUTC()));
        this.productInstanceRepository.save(productInstanceEntity);
        return productInstance.getAccountIdentifier();
      } else {
        this.logger.info("Skipped update for product instance {}, no data changed.", productInstance.getAccountIdentifier());
        return null;
      }
    } else {
      throw ServiceException.notFound("Product instance {0} not found.", productInstance.getAccountIdentifier());
    }
  }

  @Transactional
  @CommandHandler
  @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_PRODUCT_INSTANCE)
  public String process(final TransactionProcessedCommand transactionProcessedCommand) {
    final Optional<ProductInstanceEntity> optionalProductInstance =
        this.productInstanceRepository.findByAccountIdentifier(transactionProcessedCommand.accountIdentifier());

    final ProductInstanceEntity productInstanceEntity = optionalProductInstance.orElseThrow(() ->
        ServiceException.notFound("Product instance {0} not found.", transactionProcessedCommand.accountIdentifier()));

    productInstanceEntity.setLastTransactionDate(LocalDateTime.now(Clock.systemUTC()));
    
    this.productInstanceRepository.save(productInstanceEntity);

    return transactionProcessedCommand.accountIdentifier();
  }

  private boolean hasChanged(final ProductInstance productInstance, final ProductInstanceEntity productInstanceEntity) {
    if (productInstance.getBeneficiaries() != null) {
      if (productInstanceEntity.getBeneficiaries() == null) {
        return true;
      }

      final HashSet<String> knownBeneficiaries = new HashSet<>(
          Arrays.asList(StringUtils.split(productInstanceEntity.getBeneficiaries(), ","))
      );

      if (knownBeneficiaries.size() != productInstance.getBeneficiaries().size()
          || !knownBeneficiaries.containsAll(productInstance.getBeneficiaries())) {
        return true;
      }
    }

    return productInstanceEntity.getBeneficiaries() == null;
  }
}
