/*
    SPDX-FileCopyrightText: 2000-2003 Michael Edwardes <mte@users.sourceforge.net>
    SPDX-FileCopyrightText: 2000-2003 Javier Campos Morales <javi_c@users.sourceforge.net>
    SPDX-FileCopyrightText: 2000-2003 Felix Rodriguez <frodriguez@users.sourceforge.net>
    SPDX-FileCopyrightText: 2000-2003 John C <thetacoturtle@users.sourceforge.net>
    SPDX-FileCopyrightText: 2000-2003 Thomas Baumgart <ipwizard@users.sourceforge.net>
    SPDX-FileCopyrightText: 2000-2003 Kevin Tambascio <ktambascio@users.sourceforge.net>
    SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "knewloanwizard.h"
#include "knewloanwizard_p.h"

// ----------------------------------------------------------------------------
// QT Includes

#include <QList>

// ----------------------------------------------------------------------------
// KDE Includes

// ----------------------------------------------------------------------------
// Project Includes

#include "knewaccountdlg.h"
#include "mymoneypayee.h"

KNewLoanWizard::KNewLoanWizard(QWidget *parent) :
    QWizard(parent),
    d_ptr(new KNewLoanWizardPrivate(this))
{
    Q_D(KNewLoanWizard);
    d->init();
}

KNewLoanWizard::KNewLoanWizard(KNewLoanWizardPrivate &dd, QWidget *parent) :
    QWizard(parent),
    d_ptr(&dd)
{
    Q_D(KNewLoanWizard);
    d->init();
}

KNewLoanWizard::~KNewLoanWizard()
{
}

const MyMoneyAccountLoan KNewLoanWizard::account() const
{
    Q_D(const KNewLoanWizard);
    return d->m_account;
}

int KNewLoanWizard::nextId() const
{
    Q_D(const KNewLoanWizard);
    // Starting from the current page, look for the first enabled page
    // and return that value
    // If the end of the list is encountered first, then return -1.
    for (int i = currentId() + 1; i < d->m_pages.size() && i < pageIds().size(); ++i) {
        if (d->m_pages.testBit(i))
            return pageIds()[i];
    }
    return -1;
}

bool KNewLoanWizard::validateCurrentPage()
{
    Q_D(KNewLoanWizard);
    auto dontLeavePage = false;
    KLocalizedString ks = ki18n(
                              "The loan wizard is unable to calculate two different values for your loan "
                              "at the same time. "
                              "Please enter a value for the %1 on this page or backup to the page where the "
                              "current value to be calculated is defined and fill in a value.");

    if (currentPage() == d->ui->m_lendBorrowPage) {
        // load the appropriate categories into the list
        d->loadAccountList();

    } else if (currentPage() == d->ui->m_interestTypePage) {
        if (field("fixedInterestButton").toBool()) {
            d->m_pages.setBit(Page_PreviousPayments);
            if (field("previousPaymentButton").toBool())
                d->m_pages.setBit(Page_RecordPayment);
            else
                d->m_pages.clearBit(Page_RecordPayment);
            d->m_pages.clearBit(Page_VariableInterestDate);

        } else {
            d->m_pages.clearBit(Page_PreviousPayments);
            d->m_pages.clearBit(Page_RecordPayment);
            d->m_pages.setBit(Page_VariableInterestDate);
        }

    } else if (currentPage() == d->ui->m_previousPaymentsPage) {
        if (field("previousPaymentButton").toBool()) {
            d->m_pages.setBit(Page_RecordPayment);
        } else if (field("noPreviousPaymentButton").toBool()) {
            d->m_pages.clearBit(Page_RecordPayment);
        }
    } else if (currentPage() == d->ui->m_loanAmountPage) {
        if (field("thisYearPaymentButton").toBool()
                && !field("loanAmountEditValid").toBool()) {
            dontLeavePage = true;
            KMessageBox::error(nullptr,
                               i18n("You selected, that payments have already been made towards this loan. "
                                    "This requires you to enter the loan amount exactly as found on your "
                                    "last statement."),
                               i18n("Calculation error"));
        } else
            d->updateLoanAmount();

    } else if (currentPage() == d->ui->m_interestPage) {

        if (!field("loanAmountEditValid").toBool()
                && !field("interestRateEditValid").toBool()) {
            dontLeavePage = true;
            KMessageBox::error(nullptr, ks.subs(i18n("interest rate")).toString(), i18n("Calculation error"));
        } else
            d->updateInterestRate();

    } else if (currentPage() == d->ui->m_durationPage) {
        if ((!field("loanAmountEditValid").toBool()
                || !field("interestRateEditValid").toBool())
                && field("durationValueEdit").toInt() == 0) {
            dontLeavePage = true;
            KMessageBox::error(nullptr, ks.subs(i18n("term")).toString(), i18n("Calculation error"));
        } else
            d->updateDuration();

    } else if (currentPage() == d->ui->m_paymentPage) {
        if ((!field("loanAmountEditValid").toBool()
                || !field("interestRateEditValid").toBool()
                || field("durationValueEdit").toInt() == 0)
                && !field("paymentEditValid").toBool()) {
            dontLeavePage = true;
            KMessageBox::error(nullptr, ks.subs(i18n("principal and interest")).toString(), i18n("Calculation error"));
        } else
            d->updatePayment();

    } else if (currentPage() == d->ui->m_finalPaymentPage) {
        if ((!field("loanAmountEditValid").toBool()
                || !field("interestRateEditValid").toBool()
                || field("durationValueEdit").toInt() == 0
                || !field("paymentEditValid").toBool())
                && !field("finalPaymentEditValid").toBool()) {
            // if two fields are empty and one of them is the final payment
            // we assume the final payment to be 0 instead of presenting a dialog
            setField("finalPaymentEdit", QVariant::fromValue<MyMoneyMoney>((MyMoneyMoney())));
        }
        d->updateFinalPayment();
        if (!d->calculateLoan()) {
            dontLeavePage = true;
        } else
            d->updateLoanInfo();
    } else if (currentPage() == d->ui->m_schedulePage) {
        if (field("allPaymentsButton").toBool() || field("noPreviousPaymentButton").toBool()) {
            if (d->ui->m_assetAccountPage)
                d->m_pages.setBit(Page_AssetAccount);
        } else {
            if (d->ui->m_assetAccountPage) {
                d->m_pages.clearBit(Page_AssetAccount);
                if (d->ui->m_assetAccountPage->ui && d->ui->m_assetAccountPage->ui->m_assetAccountEdit) {
                    d->ui->m_assetAccountPage->ui->m_assetAccountEdit->slotDeselectAllAccounts();
                }
            }
        }
    }

    if (!dontLeavePage)
        return true;
    else
        return false;
}

MyMoneySchedule KNewLoanWizard::schedule() const
{
    MyMoneySchedule sched(field("nameEdit").toString(),
                          eMyMoney::Schedule::Type::LoanPayment,
                          eMyMoney::Schedule::Occurrence(field("paymentFrequencyUnitEdit").toInt()), 1,
                          eMyMoney::Schedule::PaymentType::Other,
                          QDate(),
                          QDate(),
                          false,
                          false);

    Q_D(const KNewLoanWizard);
    MyMoneyTransaction t = d->transaction();
    t.setPostDate(field("nextDueDateEdit").toDate());
    sched.setTransaction(t);

    return sched;
}

void KNewLoanWizard::slotReloadEditWidgets()
{
    Q_D(KNewLoanWizard);
    // load the various account widgets
    d->loadAccountList();

    // reload payee widget
    auto payeeId = field("payeeEdit").toString();

    //FIXME: port
    d->ui->m_namePage->ui->m_payeeEdit->loadPayees(MyMoneyFile::instance()->payeeList());

    if (!payeeId.isEmpty()) {
        setField("payeeEdit", payeeId);
    }
}

QString KNewLoanWizard::initialPaymentAccount() const
{
    if (field("dontCreatePayoutCheckBox").toBool()) {
        return QString();
    }
    return field("assetAccountEdit").toStringList().first();
}

QDate KNewLoanWizard::initialPaymentDate() const
{
    if (field("dontCreatePayoutCheckBox").toBool()) {
        return QDate();
    }
    return field("paymentDate").toDate();
}

void KNewLoanWizard::slotNewCategory(MyMoneyAccount& acc)
{
    KNewAccountDlg::newCategory(acc, MyMoneyAccount());
}

void KNewLoanWizard::slotNewPayee(const QString& newnameBase, QString& id)
{
    bool ok;
    std::tie(ok, id) = KMyMoneyUtils::newPayee(newnameBase);
}
