/*
 * Copyright (C) 2014-2024 CZ.NIC
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations including
 * the two.
 */

#include <QPushButton>

#include "src/dimensions/dimensions.h"
#include "src/global.h"
#include "src/gui/dlg_contacts.h"
#include "src/settings/prefs_specific.h"
#include "src/views/table_home_end_filter.h"
#include "src/views/table_space_selection_filter.h"
#include "src/views/table_tab_ignore_filter.h"
#include "ui_dlg_contacts.h"

static const QString dlgName("contacts");
static const QString databoxTableName("databox_list");

DlgContacts::DlgContacts(const MessageDbSet &dbSet, QStringList *dbIdList,
    QWidget *parent)
    : QDialog(parent),
    m_ui(new (::std::nothrow) Ui::DlgContacts),
    m_contactListProxyModel(this),
    m_dfltFilerLineStyleSheet(SortFilterProxyModel::invalidFilterEditStyle),
    m_contactTableModel(this),
    m_dbIdList(dbIdList)
{
	m_ui->setupUi(this);
	/* Tab order is defined in UI file. */

	/* Set default line height for table views/widgets. */
	m_ui->contactTableView->setNarrowedLineHeight();
	m_ui->contactTableView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
	m_ui->contactTableView->setSelectionMode(
	    QAbstractItemView::ExtendedSelection);
	m_ui->contactTableView->setSelectionBehavior(
	    QAbstractItemView::SelectRows);

	m_contactTableModel.setHeader();
	m_contactListProxyModel.setSortRole(BoxContactsModel::ROLE_PROXYSORT);
	m_contactListProxyModel.setSourceModel(&m_contactTableModel);
	{
		QList<int> columnList;
		columnList.append(BoxContactsModel::BOX_ID_COL);
		columnList.append(BoxContactsModel::BOX_NAME_COL);
		columnList.append(BoxContactsModel::ADDRESS_COL);
		m_contactListProxyModel.setFilterKeyColumns(columnList);
	}
	m_ui->contactTableView->setModel(&m_contactListProxyModel);

	m_ui->contactTableView->setSortingEnabled(true);
	m_ui->contactTableView->sortByColumn(BoxContactsModel::BOX_ID_COL, Qt::AscendingOrder);

	m_ui->contactTableView->setSquareColumnWidth(BoxContactsModel::CHECKBOX_COL);
	m_ui->contactTableView->setColumnWidth(BoxContactsModel::BOX_ID_COL, 70);
	m_ui->contactTableView->setColumnWidth(BoxContactsModel::BOX_NAME_COL, 150);

	m_ui->contactTableView->setColumnHidden(BoxContactsModel::BOX_TYPE_COL,
	    true);
	m_ui->contactTableView->setColumnHidden(BoxContactsModel::POST_CODE_COL,
	    true);
	m_ui->contactTableView->setColumnHidden(BoxContactsModel::PUBLIC_COL,
	    true);
	m_ui->contactTableView->setColumnHidden(BoxContactsModel::PDZ_COL,
	    true);
	m_ui->contactTableView->setColumnHidden(BoxContactsModel::PAYMENT_COL,
	    true);
	m_ui->contactTableView->setColumnHidden(BoxContactsModel::PAYMENTS_COL,
	    true);

	m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);

	fillContactsFromMessageDb(dbSet);

	m_ui->filterLine->setToolTip(tr("Enter sought expression"));
	m_ui->filterLine->setClearButtonEnabled(true);

	connect(m_ui->filterLine, SIGNAL(textChanged(QString)),
	    this, SLOT(filterContact(QString)));
	connect(&m_contactTableModel,
	    SIGNAL(dataChanged(QModelIndex, QModelIndex)),
	    this, SLOT(enableOkButton()));
	connect(m_ui->contactTableView, SIGNAL(doubleClicked(QModelIndex)),
	    this, SLOT(contactItemDoubleClicked(QModelIndex)));
	connect(m_ui->buttonBox, SIGNAL(accepted()),
	    this, SLOT(addSelectedDbIDs()));

	m_ui->contactTableView->setEditTriggers(
	    QAbstractItemView::NoEditTriggers);

	m_ui->contactTableView->installEventFilter(
	    new (::std::nothrow) TableHomeEndFilter(m_ui->contactTableView));
	m_ui->contactTableView->installEventFilter(
	    new (::std::nothrow) TableSpaceSelectionFilter(
	        BoxContactsModel::CHECKBOX_COL, m_ui->contactTableView));
	m_ui->contactTableView->installEventFilter(
	    new (::std::nothrow) TableTabIgnoreFilter(m_ui->contactTableView));
}

DlgContacts::~DlgContacts(void)
{
	PrefsSpecific::setDlgTblRelColWidths(*GlobInstcs::prefsPtr,
	    dlgName, databoxTableName,
	    Dimensions::relativeTableColumnWidths(m_ui->contactTableView));
	PrefsSpecific::setDlgTblColSortOrder(*GlobInstcs::prefsPtr,
	    dlgName, databoxTableName,
	    Dimensions::tableColumnSortOrder(m_ui->contactTableView));

	delete m_ui;
}

bool DlgContacts::selectContacts(const MessageDbSet &dbSet,
    QStringList *dbIdList, QWidget *parent)
{
	DlgContacts dlg(dbSet, dbIdList, parent);

	const QSize dfltSize = dlg.size();
	{
		const QSize newSize = Dimensions::dialogueSize(&dlg,
		    PrefsSpecific::dlgSize(*GlobInstcs::prefsPtr, dlgName),
		    dfltSize);
		if (newSize.isValid()) {
			dlg.resize(newSize);
		}
	}

	int ret = dlg.exec();

	PrefsSpecific::setDlgSize(*GlobInstcs::prefsPtr, dlgName,
	    dlg.size(), dfltSize);

	return QDialog::Accepted == ret;
}

void DlgContacts::showEvent(QShowEvent *event)
{
	QDialog::showEvent(event);

	Dimensions::setRelativeTableColumnWidths(m_ui->contactTableView,
	    PrefsSpecific::dlgTblRelColWidths(*GlobInstcs::prefsPtr,
	    dlgName, databoxTableName));
	Dimensions::setTableColumnSortOrder(m_ui->contactTableView,
	    PrefsSpecific::dlgTblColSortOrder(*GlobInstcs::prefsPtr,
	    dlgName, databoxTableName));
}

void DlgContacts::enableOkButton(void)
{
	m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
	    m_contactTableModel.somethingChecked());
}

void DlgContacts::contactItemDoubleClicked(const QModelIndex &index)
{
	if (index.isValid() && (m_dbIdList != Q_NULLPTR)) {
		m_dbIdList->append(index.sibling(index.row(),
		    BoxContactsModel::BOX_ID_COL).data(
		        Qt::DisplayRole).toString());
	}
	this->accept();
}

void DlgContacts::addSelectedDbIDs(void) const
{
	if (m_dbIdList != Q_NULLPTR) {
		m_dbIdList->append(m_contactTableModel.boxIdentifiers(
		    BoxContactsModel::CHECKED));
	}
}

void DlgContacts::filterContact(const QString &text)
{
	/* Store style at first invocation. */
	if (m_dfltFilerLineStyleSheet == SortFilterProxyModel::invalidFilterEditStyle) {
		m_dfltFilerLineStyleSheet = m_ui->filterLine->styleSheet();
	}

#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
	m_contactListProxyModel.setFilterRegularExpression(
	    QRegularExpression(QRegularExpression::escape(text),
	        QRegularExpression::CaseInsensitiveOption));
#else /* < Qt-5.15 */
	m_contactListProxyModel.setFilterRegExp(QRegExp(text,
	    Qt::CaseInsensitive, QRegExp::FixedString));
#endif /* >= Qt-5.15 */
	/* Set filter field background colour. */
	if (text.isEmpty()) {
		m_ui->filterLine->setStyleSheet(m_dfltFilerLineStyleSheet);
	} else if (m_contactListProxyModel.rowCount() != 0) {
		m_ui->filterLine->setStyleSheet(
		    SortFilterProxyModel::foundFilterEditStyle);
	} else {
		m_ui->filterLine->setStyleSheet(
		    SortFilterProxyModel::notFoundFilterEditStyle);
	}
}

void DlgContacts::fillContactsFromMessageDb(const MessageDbSet &dbSet)
{
	m_ui->contactTableView->setEnabled(false);
	m_contactTableModel.removeRows(0, m_contactTableModel.rowCount());

	QList<MessageDb::ContactEntry> foundBoxes(dbSet.uniqueContacts());

	m_ui->contactTableView->setEnabled(true);
	m_contactTableModel.appendData(foundBoxes);

	if (m_contactTableModel.rowCount() > 0) {
		m_ui->contactTableView->selectColumn(
		    BoxContactsModel::CHECKBOX_COL);
		m_ui->contactTableView->selectRow(0);
	}

	//m_ui->contactTableView->resizeColumnsToContents();
}
