/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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 org.apache.fineract.portfolio.loanaccount.domain;

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.infrastructure.event.business.domain.loan.LoanStatusChangedBusinessEvent;
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
import org.springframework.stereotype.Component;

// TODO: introduce tests for the state machine
@Component
@RequiredArgsConstructor
public class DefaultLoanLifecycleStateMachine implements LoanLifecycleStateMachine {

    private static final List<LoanStatus> ALLOWED_LOAN_STATUSES = List.of(LoanStatus.values());
    private final BusinessEventNotifierService businessEventNotifierService;

    @Override
    public LoanStatus dryTransition(final LoanEvent loanEvent, final Loan loan) {
        LoanStatus newStatus = getNextStatus(loanEvent, loan);
        return newStatus != null ? newStatus : loan.getStatus();
    }

    @Override
    public void transition(final LoanEvent loanEvent, final Loan loan) {
        LoanStatus newStatus = getNextStatus(loanEvent, loan);
        if (newStatus != null) {
            Integer newPlainStatus = newStatus.getValue();
            loan.setLoanStatus(newPlainStatus);

            if (isNotLoanCreation(loanEvent)) {
                // in case of Loan creation, a LoanCreatedBusinessEvent is also raised, no need to send a status change
                businessEventNotifierService.notifyPostBusinessEvent(new LoanStatusChangedBusinessEvent(loan));
            }
        }
    }

    private boolean isNotLoanCreation(LoanEvent loanEvent) {
        return !LoanEvent.LOAN_CREATED.equals(loanEvent);
    }

    private LoanStatus getNextStatus(LoanEvent loanEvent, Loan loan) {
        Integer plainFrom = loan.getPlainStatus();
        if (loanEvent.equals(LoanEvent.LOAN_CREATED) && plainFrom == null) {
            return submittedTransition();
        }

        LoanStatus from = loan.getStatus();
        LoanStatus newState = null;

        switch (loanEvent) {
            case LOAN_REJECTED:
                if (from.hasStateOf(LoanStatus.SUBMITTED_AND_PENDING_APPROVAL)) {
                    newState = rejectedTransition();
                }
            break;
            case LOAN_APPROVED:
                if (from.hasStateOf(LoanStatus.SUBMITTED_AND_PENDING_APPROVAL)) {
                    newState = approvedTransition();
                }
            break;
            case LOAN_WITHDRAWN:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.SUBMITTED_AND_PENDING_APPROVAL)) {
                    newState = withdrawnByClientTransition();
                }
            break;
            case LOAN_DISBURSED:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.APPROVED, LoanStatus.CLOSED_OBLIGATIONS_MET)) {
                    newState = activeTransition();
                } else if (from.isOverpaid() && loan.getTotalOverpaidAsMoney().isZero()) {
                    newState = activeTransition();
                }
            break;
            case LOAN_APPROVAL_UNDO:
                if (from.hasStateOf(LoanStatus.APPROVED)) {
                    newState = submittedTransition();
                }
            break;
            case LOAN_DISBURSAL_UNDO:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE)) {
                    newState = approvedTransition();
                }
            break;
            case LOAN_CHARGE_PAYMENT:
            case LOAN_REPAYMENT_OR_WAIVER:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.CLOSED_OBLIGATIONS_MET, LoanStatus.OVERPAID)) {
                    newState = activeTransition();
                }
            break;
            case REPAID_IN_FULL:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE, LoanStatus.OVERPAID)) {
                    newState = closeObligationsMetTransition();
                }
            break;
            case WRITE_OFF_OUTSTANDING:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE)) {
                    newState = closedWrittenOffTransition();
                }
            break;
            case LOAN_RESCHEDULE:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.ACTIVE)) {
                    newState = closedRescheduleOutstandingAmountTransition();
                }
            break;
            case LOAN_OVERPAYMENT:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.CLOSED_OBLIGATIONS_MET, LoanStatus.ACTIVE)) {
                    newState = overpaidTransition();
                }
            break;
            case LOAN_ADJUST_TRANSACTION:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.CLOSED_OBLIGATIONS_MET, LoanStatus.CLOSED_WRITTEN_OFF,
                        LoanStatus.CLOSED_RESCHEDULE_OUTSTANDING_AMOUNT)) {
                    newState = activeTransition();
                }
            break;
            case LOAN_INITIATE_TRANSFER:
                newState = transferInProgress();
            break;
            case LOAN_REJECT_TRANSFER:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.TRANSFER_IN_PROGRESS)) {
                    newState = transferOnHold();
                }
            break;
            case LOAN_WITHDRAW_TRANSFER:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.TRANSFER_IN_PROGRESS)) {
                    newState = activeTransition();
                }
            break;
            case WRITE_OFF_OUTSTANDING_UNDO:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.CLOSED_WRITTEN_OFF)) {
                    newState = activeTransition();
                }
            break;
            case LOAN_CREDIT_BALANCE_REFUND:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.OVERPAID)) {
                    newState = closeObligationsMetTransition();
                }
            break;
            case LOAN_CHARGE_ADDED:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.CLOSED_OBLIGATIONS_MET)) {
                    newState = activeTransition();
                }
            break;
            case LOAN_CHARGEBACK:
                if (anyOfAllowedWhenComingFrom(from, LoanStatus.CLOSED_OBLIGATIONS_MET, LoanStatus.OVERPAID)) {
                    newState = activeTransition();
                }
            break;
            case LOAN_CHARGE_ADJUSTMENT:
                if (from.hasStateOf(LoanStatus.CLOSED_OBLIGATIONS_MET)) {
                    newState = overpaidTransition();
                }
            break;
            default:
            break;
        }
        return newState;
    }

    private LoanStatus transferOnHold() {
        return stateOf(LoanStatus.TRANSFER_ON_HOLD, ALLOWED_LOAN_STATUSES);
    }

    private LoanStatus transferInProgress() {
        return stateOf(LoanStatus.TRANSFER_IN_PROGRESS, ALLOWED_LOAN_STATUSES);
    }

    private LoanStatus overpaidTransition() {
        return stateOf(LoanStatus.OVERPAID, ALLOWED_LOAN_STATUSES);
    }

    private LoanStatus closedRescheduleOutstandingAmountTransition() {
        return stateOf(LoanStatus.CLOSED_RESCHEDULE_OUTSTANDING_AMOUNT, ALLOWED_LOAN_STATUSES);
    }

    private LoanStatus closedWrittenOffTransition() {
        return stateOf(LoanStatus.CLOSED_WRITTEN_OFF, ALLOWED_LOAN_STATUSES);
    }

    private LoanStatus closeObligationsMetTransition() {
        return stateOf(LoanStatus.CLOSED_OBLIGATIONS_MET, ALLOWED_LOAN_STATUSES);
    }

    private LoanStatus activeTransition() {
        return stateOf(LoanStatus.ACTIVE, ALLOWED_LOAN_STATUSES);
    }

    private LoanStatus withdrawnByClientTransition() {
        return stateOf(LoanStatus.WITHDRAWN_BY_CLIENT, ALLOWED_LOAN_STATUSES);
    }

    private LoanStatus approvedTransition() {
        return stateOf(LoanStatus.APPROVED, ALLOWED_LOAN_STATUSES);
    }

    private LoanStatus rejectedTransition() {
        return stateOf(LoanStatus.REJECTED, ALLOWED_LOAN_STATUSES);
    }

    private LoanStatus submittedTransition() {
        return stateOf(LoanStatus.SUBMITTED_AND_PENDING_APPROVAL, ALLOWED_LOAN_STATUSES);
    }

    private LoanStatus stateOf(final LoanStatus state, final List<LoanStatus> allowedLoanStatuses) {
        LoanStatus match = null;
        for (final LoanStatus loanStatus : allowedLoanStatuses) {
            if (loanStatus.hasStateOf(state)) {
                match = loanStatus;
                break;
            }
        }
        return match;
    }

    private boolean anyOfAllowedWhenComingFrom(final LoanStatus state, final LoanStatus... allowedStates) {
        boolean allowed = false;

        for (final LoanStatus allowedState : allowedStates) {
            if (state.hasStateOf(allowedState)) {
                allowed = true;
                break;
            }
        }

        return allowed;
    }
}
