/*
 * 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.service;

import io.mifos.core.lang.ServiceException;
import io.mifos.portfolio.api.v1.domain.Case;
import io.mifos.portfolio.api.v1.domain.CasePage;
import io.mifos.portfolio.api.v1.domain.CostComponent;
import io.mifos.portfolio.service.internal.mapper.CaseMapper;
import io.mifos.portfolio.service.internal.pattern.PatternFactoryRegistry;
import io.mifos.portfolio.service.internal.repository.CaseEntity;
import io.mifos.portfolio.service.internal.repository.CaseRepository;
import io.mifos.portfolio.service.internal.repository.ProductEntity;
import io.mifos.portfolio.service.internal.repository.ProductRepository;
import io.mifos.products.spi.PatternFactory;
import io.mifos.products.spi.ProductCommandDispatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Myrle Krantz
 */
@Service
public class CaseService {
  private final PatternFactoryRegistry patternFactoryRegistry;
  private final ProductRepository productRepository;
  private final CaseRepository caseRepository;

  @Autowired
  public CaseService(
          final PatternFactoryRegistry patternFactoryRegistry,
          final ProductRepository productRepository,
          final CaseRepository caseRepository) {
    this.patternFactoryRegistry = patternFactoryRegistry;
    this.productRepository = productRepository;
    this.caseRepository = caseRepository;
  }

  public CasePage findAllEntities(final String productIdentifier,
                                  final Boolean includeClosed,
                                  final int pageIndex,
                                  final int size) {
    final Pageable pageRequest = new PageRequest(pageIndex, size, Sort.Direction.DESC, "lastModifiedOn");

    Stream<Case.State> currentStatesStream = Arrays.stream(Case.State.values());
    if (!includeClosed)
      currentStatesStream = currentStatesStream.filter(x -> x != Case.State.CLOSED);
    final List<String> currentStates = currentStatesStream.map(Enum::name).collect(Collectors.toList());

    final Page<CaseEntity> ret = caseRepository.findByProductIdentifierAndCurrentStateIn(productIdentifier, currentStates, pageRequest);
    final int minorCurrencyUnitDigits = getMinorCurrencyUnitDigits(productIdentifier);

    return new CasePage(mapList(ret.getContent(), minorCurrencyUnitDigits), ret.getTotalPages(), ret.getTotalElements());
  }

  private List<Case> mapList(final List<CaseEntity> in,
                             final int minorCurrencyUnitDigits) {
    return in.stream()
            .map(caseEntity -> map(caseEntity, minorCurrencyUnitDigits))
            .filter(Optional::isPresent)
            .map(Optional::get)
            .collect(Collectors.toList());
  }

  public Optional<Case> findByIdentifier(final String productIdentifier, final String caseIdentifier)
  {
    final int minorCurrencyUnitDigits = getMinorCurrencyUnitDigits(productIdentifier);
    return caseRepository.findByProductIdentifierAndIdentifier(productIdentifier, caseIdentifier)
            .flatMap(caseEntity -> map(caseEntity, minorCurrencyUnitDigits));
  }

  public Set<String> getNextActionsForCase(final String productIdentifier, final String caseIdentifier) {
    final PatternFactory pattern = getPatternFactoryOrThrow(productIdentifier);

    return caseRepository.findByProductIdentifierAndIdentifier(productIdentifier, caseIdentifier)
            .map(x -> pattern.getNextActionsForState(Case.State.valueOf(x.getCurrentState())))
            .orElseThrow(() -> ServiceException.notFound("Case with identifier ''" + productIdentifier + "." + caseIdentifier + "'' doesn''t exist."));
  }

  public ProductCommandDispatcher getProductCommandDispatcher(final String productIdentifier) {
    return getPatternFactoryOrThrow(productIdentifier).getIndividualLendingCommandDispatcher();
  }

  private Optional<Case> map(final CaseEntity caseEntity, final int minorCurrencyUnitDigits) {
    return getPatternFactory(caseEntity.getProductIdentifier())
            .flatMap(x -> x.getParameters(caseEntity.getId(), minorCurrencyUnitDigits))
            .map(x -> CaseMapper.map(caseEntity, x));
  }

  private PatternFactory getPatternFactoryOrThrow(final String productIdentifier) {
    return getPatternFactory(productIdentifier)
            .orElseThrow(() -> ServiceException.notFound("Product with identifier ''" + productIdentifier + "'' doesn''t exist."));
  }

  private Optional<PatternFactory> getPatternFactory(final String productIdentifier) {
    return productRepository.findByIdentifier(productIdentifier)
              .map(ProductEntity::getPatternPackage)
              .flatMap(patternFactoryRegistry::getPatternFactoryForPackage);
  }

  public boolean existsByProductIdentifier(final String productIdentifier) {
    return caseRepository.existsByProductIdentifier(productIdentifier);
  }

  public boolean existsByIdentifier(final String productIdentifier,
                                    final String caseIdentifier) {
    return this.findByIdentifier(productIdentifier, caseIdentifier).isPresent();
  }

  public List<CostComponent> getActionCostComponentsForCase(final String productIdentifier,
                                                            final String caseIdentifier,
                                                            final String actionIdentifier) {
    return getPatternFactoryOrThrow(productIdentifier)
            .getCostComponentsForAction(productIdentifier, caseIdentifier, actionIdentifier);
  }

  private int getMinorCurrencyUnitDigits(final String productIdentifier) {
    return productRepository.findByIdentifier(productIdentifier)
        .map(ProductEntity::getMinorCurrencyUnitDigits)
        .orElse(4);
  }
}