// Copyright 2019-2021 The Hush developers
// Released under the GPLv3
#include "requestdialog.h"
#include "ui_requestdialog.h"
#include "settings.h"
#include "addressbook.h"
#include "mainwindow.h"
#include "controller.h"
#include "settings.h"

#include "precompiled.h"

RequestDialog::RequestDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::RequestDialog)
{
    ui->setupUi(this);
}

RequestDialog::~RequestDialog()
{
    delete ui;
}

void RequestDialog::setupDialog(MainWindow* main, QDialog* d, Ui_RequestDialog* req) {
    req->setupUi(d);
    Settings::saveRestore(d);

    // Setup
    req->txtMemo->setLenDisplayLabel(req->lblMemoLen);
    req->lblAmount->setText(req->lblAmount->text() + Settings::getTokenName());

    if (!main || !main->getRPC())
        return;

    for (auto addr : main->getRPC()->getModel()->getAllZAddresses()) {
        auto bal = main->getRPC()->getModel()->getAllBalances().value(addr);
        if (Settings::getInstance()->isSaplingAddress(addr)) {
            req->cmbMyAddress->addItem(addr, bal);
        }
    }
    req->cmbMyAddress->setCurrentText(main->getRPC()->getDefaultSaplingAddress());

    QIcon icon(":/icons/res/paymentreq.gif");
    req->lblPixmap->setPixmap(icon.pixmap(48, 48));
}

// Static method that shows an incoming payment request and prompts the user to pay it
void RequestDialog::showPaymentConfirmation(MainWindow* main, QString paymentURI) {
    PaymentURI payInfo = Settings::parseURI(paymentURI);
    if (!payInfo.error.isEmpty()) {
        QMessageBox::critical(main, tr("Error paying hush URI"), 
                tr("URI should be of the form 'hush:<addr>?amt=x&memo=y") + "\n" + payInfo.error);
        return;
    }

    QDialog d(main);
    Ui_RequestDialog req;
    setupDialog(main, &d, &req);    

    // In the view mode, all fields are read-only
    req.txtAmount->setReadOnly(true);
    req.txtFrom->setReadOnly(true);
    req.txtMemo->setReadOnly(true);

    // Payment is "to"
    req.lblAddress->setText(tr("Pay To"));

    // No Addressbook
    req.btnAddressBook->setVisible(false);

    // No "address is visible" warning
    req.lblAddressInfo->setVisible(false);

    req.txtFrom->setText(payInfo.addr);
    req.txtMemo->setPlainText(payInfo.memo);
    req.txtAmount->setText(payInfo.amt);
    CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
    if (Settings::getInstance()->get_currency_name() == "USD") {
    req.txtAmountUSD->setText(amount.toDecimalUSDString());
    } else if (Settings::getInstance()->get_currency_name() == "EUR") {
        req.txtAmountUSD->setText(amount.toDecimalEURString());
        } else if (Settings::getInstance()->get_currency_name() == "BTC") {
            req.txtAmountUSD->setText(amount.toDecimalBTCString());
        }

    req.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Pay"));

    req.lblHeader->setText(tr("You are paying a payment request. Your address will not be visible to the person requesting this payment."));

    if (d.exec() == QDialog::Accepted) {
        main->payhushURI(paymentURI, req.cmbMyAddress->currentText());
    }
}

// Static method that shows the request dialog
void RequestDialog::showRequesthush(MainWindow* main) {
    QDialog d(main);
    Ui_RequestDialog req;

    setupDialog(main, &d, &req);

    // Setup the Label completer for the Address
    req.txtFrom->setCompleter(main->getLabelCompleter());
    QObject::connect(req.txtFrom, &QLineEdit::textChanged, [=] (auto text) {
        auto addr = AddressBook::addressFromAddressLabel(text);
        if (!Settings::getInstance()->isSaplingAddress(addr)) {
            req.lblSaplingWarning->setText(tr("Can only request from Sapling addresses"));
            req.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
        } else {
            req.lblSaplingWarning->setText("");
            req.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
        }
    });

    // Wire up AddressBook button
    QObject::connect(req.btnAddressBook, &QPushButton::clicked, [=] () {
        AddressBook::open(main, req.txtFrom);
    });

    // Amount textbox
    req.txtAmount->setValidator(main->getAmountValidator());
    QObject::connect(req.txtAmount, &QLineEdit::textChanged, [=] (auto text) {
        CAmount amount = CAmount::fromDecimalString(text);
     if (Settings::getInstance()->get_currency_name() == "USD") {
         req.txtAmountUSD->setText(amount.toDecimalUSDString());
    } else if (Settings::getInstance()->get_currency_name() == "EUR") {
        req.txtAmountUSD->setText(amount.toDecimalEURString());
    } else if (Settings::getInstance()->get_currency_name() == "BTC") {
        req.txtAmountUSD->setText(amount.toDecimalBTCString());
    } else if (Settings::getInstance()->get_currency_name() == "CNY") {
        req.txtAmountUSD->setText(amount.toDecimalCNYString());
    } else if (Settings::getInstance()->get_currency_name() == "RUB") {
        req.txtAmountUSD->setText(amount.toDecimalRUBString());
    } else if (Settings::getInstance()->get_currency_name() == "CAD") {
        req.txtAmountUSD->setText(amount.toDecimalCADString());
    } else if (Settings::getInstance()->get_currency_name() == "SGD") {
        req.txtAmountUSD->setText(amount.toDecimalSGDString());
    } else if (Settings::getInstance()->get_currency_name() == "CHF") {
        req.txtAmountUSD->setText(amount.toDecimalCHFString());
    } else if (Settings::getInstance()->get_currency_name() == "INR") {
        req.txtAmountUSD->setText(amount.toDecimalINRString());
    } else if (Settings::getInstance()->get_currency_name() == "GBP") {
        req.txtAmountUSD->setText(amount.toDecimalGBPString());
    } else if (Settings::getInstance()->get_currency_name() == "AUD") {
        req.txtAmountUSD->setText(amount.toDecimalBTCString());
        }
    });
    CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
    if (Settings::getInstance()->get_currency_name() == "USD") {
         req.txtAmountUSD->setText(amount.toDecimalUSDString());
    } else if (Settings::getInstance()->get_currency_name() == "EUR") {
        req.txtAmountUSD->setText(amount.toDecimalEURString());
    } else if (Settings::getInstance()->get_currency_name() == "BTC") {
        req.txtAmountUSD->setText(amount.toDecimalBTCString());
    } else if (Settings::getInstance()->get_currency_name() == "CNY") {
        req.txtAmountUSD->setText(amount.toDecimalCNYString());
    } else if (Settings::getInstance()->get_currency_name() == "RUB") {
        req.txtAmountUSD->setText(amount.toDecimalRUBString());
    } else if (Settings::getInstance()->get_currency_name() == "CAD") {
        req.txtAmountUSD->setText(amount.toDecimalCADString());
    } else if (Settings::getInstance()->get_currency_name() == "SGD") {
        req.txtAmountUSD->setText(amount.toDecimalSGDString());
    } else if (Settings::getInstance()->get_currency_name() == "CHF") {
        req.txtAmountUSD->setText(amount.toDecimalCHFString());
    } else if (Settings::getInstance()->get_currency_name() == "INR") {
        req.txtAmountUSD->setText(amount.toDecimalINRString());
    } else if (Settings::getInstance()->get_currency_name() == "GBP") {
        req.txtAmountUSD->setText(amount.toDecimalGBPString());
    } else if (Settings::getInstance()->get_currency_name() == "AUD") {
        req.txtAmountUSD->setText(amount.toDecimalBTCString());
        }
    req.txtMemo->setAcceptButton(req.buttonBox->button(QDialogButtonBox::Ok));
    req.txtMemo->setLenDisplayLabel(req.lblMemoLen);
    req.txtMemo->setMaxLen(400);

    req.txtFrom->setFocus();

    if (d.exec() == QDialog::Accepted) {
        // Construct a hush Payment URI with the data and pay it immediately.
        CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
        QString memoURI = "hush:" + req.cmbMyAddress->currentText()
                    + "?amt=" + amount.toDecimalString()
                    + "&memo=" + QUrl::toPercentEncoding(req.txtMemo->toPlainText());

        QString sendURI = "hush:" + AddressBook::addressFromAddressLabel(req.txtFrom->text()) 
                    + "?amt=0.0001"
                    + "&memo=" + QUrl::toPercentEncoding(memoURI);

        // If the disclosed address in the memo doesn't have a balance, it will automatically fallback to the default
        // sapling address
        main->payhushURI(sendURI, req.cmbMyAddress->currentText());
    }
}
