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

import io.mifos.portfolio.api.v1.domain.PaymentCycle;
import io.mifos.individuallending.api.v1.domain.caseinstance.CaseParameters;
import io.mifos.individuallending.api.v1.domain.workflow.Action;
import org.springframework.stereotype.Service;

import javax.annotation.Nonnull;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Myrle Krantz
 */
@SuppressWarnings("WeakerAccess")
@Service
public class ScheduledActionService {

  List<ScheduledAction> getHypotheticalScheduledActions(final @Nonnull LocalDate initialDisbursalDate,
                                                                final @Nonnull CaseParameters caseParameters)
  {
    return getHypotheticalScheduledActionsHelper(initialDisbursalDate, caseParameters).collect(Collectors.toList());
  }

  private Stream<ScheduledAction> getHypotheticalScheduledActionsHelper(final @Nonnull LocalDate initialDisbursalDate,
                                                        final @Nonnull CaseParameters caseParameters)
  {
    //'Rough' end date, because if the repayment period takes the last period after that end date, then the repayment
    // period will 'win'.
    final LocalDate roughEndDate = getEndDate(caseParameters, initialDisbursalDate);

    final SortedSet<Period> repaymentPeriods = generateRepaymentPeriods(initialDisbursalDate, roughEndDate, caseParameters);
    final Period firstPeriod = repaymentPeriods.first();
    final Period lastPeriod = repaymentPeriods.last();

    return Stream.concat(Stream.of(
        new ScheduledAction(Action.OPEN, initialDisbursalDate, firstPeriod, firstPeriod),
        new ScheduledAction(Action.APPROVE, initialDisbursalDate, firstPeriod, firstPeriod),
        new ScheduledAction(Action.DISBURSE, initialDisbursalDate, firstPeriod, firstPeriod)),
        Stream.concat(repaymentPeriods.stream().flatMap(this::generateScheduledActionsForRepaymentPeriod),
            Stream.of(new ScheduledAction(Action.CLOSE, lastPeriod.getEndDate(), lastPeriod, lastPeriod))));
  }

  private LocalDate getEndDate(final @Nonnull CaseParameters caseParameters,
                               final @Nonnull LocalDate initialDisbursalDate) {
    final Integer maximumTermSize = caseParameters.getTermRange().getMaximum();
    final ChronoUnit termUnit = caseParameters.getTermRange().getTemporalUnit();

    return initialDisbursalDate.plus(
            maximumTermSize,
            termUnit);
  }

  private Stream<ScheduledAction> generateScheduledActionsForRepaymentPeriod(final @Nonnull Period repaymentPeriod) {
    return Stream.concat(generateScheduledInterestPaymentsForRepaymentPeriod(repaymentPeriod),
            Stream.of(new ScheduledAction(Action.ACCEPT_PAYMENT, repaymentPeriod.getEndDate(), repaymentPeriod, repaymentPeriod)));
  }

  private Stream<ScheduledAction> generateScheduledInterestPaymentsForRepaymentPeriod(final @Nonnull Period repaymentPeriod) {
    return getInterestDayInRepaymentPeriod(repaymentPeriod).map(x ->
            new ScheduledAction(Action.APPLY_INTEREST, x, new Period(x.minus(1, ChronoUnit.DAYS), x), repaymentPeriod));
  }

  private Stream<LocalDate> getInterestDayInRepaymentPeriod(final @Nonnull Period repaymentPeriod) {
    return Stream.iterate(repaymentPeriod.getBeginDate().plusDays(1), date -> date.plusDays(1))
            .limit(ChronoUnit.DAYS.between(repaymentPeriod.getBeginDate(), repaymentPeriod.getEndDate()));
  }

  private SortedSet<Period> generateRepaymentPeriods(
          final LocalDate initialDisbursalDate,
          final LocalDate endDate,
          final CaseParameters caseParameters) {

    final SortedSet<Period> ret = new TreeSet<>();
    LocalDate lastPaymentDate = initialDisbursalDate;
    LocalDate nextPaymentDate = generateNextPaymentDate(caseParameters, initialDisbursalDate);
    while (nextPaymentDate.isBefore(endDate))
    {
      final Period period = new Period(lastPaymentDate, nextPaymentDate);
      ret.add(period);
      lastPaymentDate = nextPaymentDate;
      nextPaymentDate = generateNextPaymentDate(caseParameters, nextPaymentDate);
    }
    ret.add(new Period(lastPaymentDate, nextPaymentDate));

    return ret;
  }

  private LocalDate generateNextPaymentDate(final CaseParameters caseParameters, final LocalDate lastPaymentDate) {
    final PaymentCycle paymentCycle = caseParameters.getPaymentCycle();

    final ChronoUnit maximumSpecifiedAlignmentChronoUnit =
            paymentCycle.getAlignmentMonth() != null ? ChronoUnit.MONTHS :
            paymentCycle.getAlignmentWeek() != null ? ChronoUnit.WEEKS :
            paymentCycle.getAlignmentDay() != null ? ChronoUnit.DAYS :
            ChronoUnit.HOURS;

    final ChronoUnit maximumPossibleAlignmentChronoUnit =
            paymentCycle.getTemporalUnit().equals(ChronoUnit.YEARS) ? ChronoUnit.MONTHS :
            paymentCycle.getTemporalUnit().equals(ChronoUnit.MONTHS) ? ChronoUnit.WEEKS :
            paymentCycle.getTemporalUnit().equals(ChronoUnit.WEEKS) ? ChronoUnit.DAYS :
            ChronoUnit.HOURS; //Hours as a placeholder.

    final ChronoUnit maximumAlignmentChronoUnit = min(maximumSpecifiedAlignmentChronoUnit, maximumPossibleAlignmentChronoUnit);


    final LocalDate incrementedPaymentDate = incrementPaymentDate(lastPaymentDate, paymentCycle);
    final LocalDate orientedPaymentDate = orientPaymentDate(incrementedPaymentDate, maximumSpecifiedAlignmentChronoUnit, paymentCycle);
    return alignPaymentDate(orientedPaymentDate, maximumAlignmentChronoUnit, paymentCycle);
  }

  private LocalDate incrementPaymentDate(LocalDate paymentDate, PaymentCycle paymentCycle) {
    return paymentDate.plus(
            paymentCycle.getPeriod(),
            paymentCycle.getTemporalUnit());
  }

  private LocalDate orientPaymentDate(final LocalDate paymentDate, final ChronoUnit maximumSpecifiedAlignmentChronoUnit, PaymentCycle paymentCycle) {
    if (maximumSpecifiedAlignmentChronoUnit == ChronoUnit.HOURS)
      return paymentDate; //No need to orient at all since no alignment is specified.

    switch (paymentCycle.getTemporalUnit())
    {
      case YEARS:
        return orientInYear(paymentDate);
      case MONTHS:
        return orientInMonth(paymentDate);
      case WEEKS:
        return orientInWeek(paymentDate);
      default:
      case DAYS:
        return paymentDate;
    }
  }

  private @Nonnull ChronoUnit min(@Nonnull final ChronoUnit a, @Nonnull final ChronoUnit b) {
    if (a.getDuration().compareTo(b.getDuration()) < 0)
      return a;
    else
      return b;
  }

  private LocalDate orientInYear(final LocalDate paymentDate) {
    return LocalDate.of(paymentDate.getYear(), 1, 1);
  }

  private LocalDate orientInMonth(final LocalDate paymentDate) {
    return LocalDate.of(paymentDate.getYear(), paymentDate.getMonth(), 1);
  }

  private LocalDate orientInWeek(final LocalDate paymentDate) {
    final DayOfWeek dayOfWeek = paymentDate.getDayOfWeek();
    final int dayOfWeekIndex = dayOfWeek.getValue() - 1;
    return paymentDate.minusDays(dayOfWeekIndex);
  }

  private LocalDate alignPaymentDate(final LocalDate paymentDate, final ChronoUnit maximumAlignmentChronoUnit, final PaymentCycle paymentCycle) {
    LocalDate ret = paymentDate;
    switch (maximumAlignmentChronoUnit)
    {
      case MONTHS:
        ret = alignInMonths(ret, paymentCycle);
      case WEEKS:
        ret = alignInWeeks(ret, paymentCycle);
      case DAYS:
        ret = alignInDays(ret, paymentCycle);
      default:
      case HOURS:
        return ret;
    }
  }

  private LocalDate alignInMonths(final LocalDate paymentDate, final PaymentCycle paymentCycle) {
    final Integer alignmentMonth = paymentCycle.getAlignmentMonth();
    if (alignmentMonth == null)
      return paymentDate;

    return paymentDate.plusMonths(alignmentMonth);
  }

  private LocalDate alignInWeeks(final LocalDate paymentDate, final PaymentCycle paymentCycle) {
    final Integer alignmentWeek = paymentCycle.getAlignmentWeek();
    if (alignmentWeek == null)
      return paymentDate;
    if ((alignmentWeek == 0) || (alignmentWeek == 1) || (alignmentWeek == 2))
      return paymentDate.plusWeeks(alignmentWeek);
    if (alignmentWeek == -1)
    {
      final LocalDate lastDayOfMonth = YearMonth.of(paymentDate.getYear(), paymentDate.getMonth()).atEndOfMonth();
      int dayOfWeek = lastDayOfMonth.getDayOfWeek().getValue() - 1;
      if (paymentCycle.getAlignmentDay() == null || dayOfWeek == paymentCycle.getAlignmentDay()) {
        return lastDayOfMonth;
      }
      else
        return lastDayOfMonth.minus(7, ChronoUnit.DAYS); //Will align days in next step.
    }

    throw new IllegalStateException("PaymentCycle.alignmentWeek should only ever be 0, 1, 2, or -1.");
  }

  private LocalDate alignInDays(final LocalDate paymentDate, final PaymentCycle paymentCycle) {
    final Integer alignmentDay = paymentCycle.getAlignmentDay();
    if (alignmentDay == null)
      return paymentDate;

    if ((paymentCycle.getAlignmentWeek() != null) || (paymentCycle.getTemporalUnit() == ChronoUnit.WEEKS))
      return alignInDaysOfWeek(paymentDate, alignmentDay);
    else
      return alignInDaysOfMonth(paymentDate, alignmentDay);
  }

  private LocalDate alignInDaysOfWeek(final LocalDate paymentDate, final Integer alignmentDay) {
    final int dayOfWeek = paymentDate.getDayOfWeek().getValue()-1;

    if (dayOfWeek < alignmentDay)
      return paymentDate.plusDays(alignmentDay - dayOfWeek);
    else if (dayOfWeek > alignmentDay)
      return paymentDate.plusDays(7 - (dayOfWeek - alignmentDay));
    else
      return paymentDate;
  }

  private LocalDate alignInDaysOfMonth(final LocalDate paymentDate, final Integer alignmentDay) {
    final int maxDay = YearMonth.of(paymentDate.getYear(), paymentDate.getMonth()).lengthOfMonth()-1;
    return paymentDate.plusDays(Math.min(maxDay, alignmentDay));
  }

  public List<ScheduledAction> getScheduledActions(final @Nonnull LocalDate initialDisbursalDate,
                                                   final CaseParameters caseParameters,
                                                   final Action action,
                                                   final LocalDate time) {
    return getHypotheticalScheduledActionsHelper(initialDisbursalDate, caseParameters)
            .filter(x -> x.actionPeriod.containsDate(time))
            .filter(x -> x.action.equals(action))
            .collect(Collectors.toList());
  }
}