#include "PasswordPromptDialog.h"
#include <QtWidgets/QApplication>
#include <QCheckBox>
#include <QComboBox>
#include <QDebug>
#include <QDialogButtonBox>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QPushButton>

Q_DECLARE_OPERATORS_FOR_FLAGS(PasswordPromptDialog::Flags)

const char* PasswordPromptDialog::translateContext = "PasswordPromptDialog";

PasswordPromptDialog::PasswordPromptDialog(Flags flags, QWidget *parent)
	: QDialog(parent)
	, m_Flags(flags)
{
	m_descriptionLabel = new QLabel(this);
	m_DialogButtons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);

	const size_t inputFieldCount = flags.testFlag(ConfirmPassword) ? 2 : 1;

	setMinimumWidth(400);
	auto mainLayout = new QGridLayout;
	mainLayout->setHorizontalSpacing(12);
	mainLayout->setVerticalSpacing(18);

	int row = 0;
	mainLayout->addWidget(m_descriptionLabel, row, 0, 1, 2);
	++row;
	for (size_t idx = 0; idx < inputFieldCount; ++idx) {
		auto lbl = new QLabel(this);
		auto input = new QLineEdit(this);
		input->setEchoMode(QLineEdit::Password);
		mainLayout->addWidget(lbl, row, 0);
		mainLayout->addWidget(input, row, 1);
		m_passwordLabel[idx] = lbl;
		m_passwordInput[idx] = input;
		++row;
	}
	if (m_Flags.testFlag(SaveOption)) {
		m_saveCheck = new QCheckBox(this);
		mainLayout->addWidget(m_saveCheck, row, 1);
		++row;
	}
	if (m_Flags.testFlag(RememberPassword)) {
		m_rememberLabel = new QLabel(this);
		mainLayout->addWidget(m_rememberLabel, row, 0);

		m_rememberChoices = new QComboBox(this);
		m_rememberChoices->addItem(tr("don't"), 0);
		m_rememberChoices->addItem(tr("1 minute"), 1);
		m_rememberChoices->addItem(tr("5 minutes"), 5);
		m_rememberChoices->addItem(tr("15 minutes"), 15);
		m_rememberChoices->addItem(tr("60 minutes"), 15);
		m_rememberChoices->addItem(tr("until termination"), -1);

		mainLayout->addWidget(m_rememberChoices, row, 1);
		++row;
	}
	mainLayout->addWidget(m_DialogButtons, row, 0, 1 ,2);
	setLayout(mainLayout);

	m_passwordInput[0]->setFocus();
	retranslateUi();

	// QMetaObject::connectSlotsByName(BackupDialog);
	connect(m_DialogButtons, &QDialogButtonBox::accepted, this, &PasswordPromptDialog::accept);
	connect(m_DialogButtons, &QDialogButtonBox::rejected, this, &PasswordPromptDialog::reject);
	connect(m_passwordInput[0], &QLineEdit::textChanged, this, &PasswordPromptDialog::passwordChanged);
	if (m_passwordInput[1])
		connect(m_passwordInput[1], &QLineEdit::textChanged, this, &PasswordPromptDialog::passwordChanged);
}

PasswordPromptDialog& PasswordPromptDialog::setDescription(const QString &description)
{
	m_descriptionLabel->setText(QString("%1").arg(description));
	return *this;
}

PasswordPromptDialog& PasswordPromptDialog::setCaption(const std::optional<QString> &caption)
{
	m_customCaption = caption;
	UpdateCaption();
	return *this;
}

PasswordPromptDialog& PasswordPromptDialog::setSaveChecked(bool save)
{
	if (m_saveCheck)
		m_saveCheck->setCheckState(save ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
	return *this;
}

void PasswordPromptDialog::UpdateCaption()
{
	QString cap = m_customCaption.value_or(QApplication::translate(translateContext, "Password dialog", nullptr));
	setWindowTitle(cap);
}

void PasswordPromptDialog::retranslateUi()
{
	UpdateCaption();
	m_passwordLabel[0]->setText(QApplication::translate(translateContext, "Password", nullptr));
	m_passwordInput[0]->setPlaceholderText(QApplication::translate(translateContext, "Enter password", nullptr));
	if (m_passwordLabel[1])
		m_passwordLabel[1]->setText(QApplication::translate(translateContext, "Confirm password", nullptr));
	if (m_passwordInput[1])
		m_passwordInput[1]->setPlaceholderText(QApplication::translate(translateContext, "Reenter same password for confirmation", nullptr));
	if (m_saveCheck)
		m_saveCheck->setText(QApplication::translate(translateContext, "Save password", nullptr));
	if (m_rememberLabel)
		m_rememberLabel->setText(QApplication::translate(translateContext, "Remember", nullptr));
}

void PasswordPromptDialog::updateOkEnabled()
{
	bool enabled = true;
	if (m_passwordInput[1])
		enabled = m_passwordInput[0]->text() == m_passwordInput[1]->text();

	auto btn = m_DialogButtons->button(QDialogButtonBox::Ok);
	btn->setEnabled(enabled);
}

void PasswordPromptDialog::passwordChanged(const QString &)
{
	updateOkEnabled();
}

QString PasswordPromptDialog::password() const
{
	return m_passwordInput[0]->text();
}

bool PasswordPromptDialog::saveChecked() const
{
	if (m_saveCheck)
		return m_saveCheck->checkState() == Qt::Checked;

	qDebug() << "PasswordPromptDialog::saveChecked() called while SaveOption flag was not passed to constructor";
	return false;
}

int PasswordPromptDialog::remember() const
{
	if (m_rememberChoices)
		return m_rememberChoices->currentData().toInt();

	qDebug() << "PasswordPromptDialog::remember() called while RememberPassword flag was not passed to constructor";
	return 0;
}
