#include "catalog/widgets/CatalogSequencesPage.h"
#include "ResultTableModelUtil.h"
#include "CustomFilterSortModel.h"
#include "CustomDataRole.h"
#include "util/PgLabItemDelegate.h"
#include "catalog/models/SequenceModel.h"
#include "widgets/SqlCodePreview.h"
#include "util/PgLabTableView.h"
#include <QHeaderView>

CatalogSequencesPage::CatalogSequencesPage(QWidget *parent)
	: QSplitter(Qt::Horizontal, parent)
{
	m_sequenceTable = new PgLabTableView(this);
	m_definitionView = new SqlCodePreview(this);

	// build widget tree
	// add top level widgets to splitter
	addWidget(m_sequenceTable);
	addWidget(m_definitionView);

	m_model = new SequenceModel(this);
	m_sortFilterProxy = new CustomFilterSortModel(this);
	m_sortFilterProxy->setSourceModel(m_model);
	m_sequenceTable->setModel(m_sortFilterProxy);
    m_sequenceTable->horizontalHeader()->setSortIndicator(SequenceModel::NameCol, Qt::AscendingOrder);
	m_sequenceTable->setSortingEnabled(true);
	m_sequenceTable->setSelectionBehavior(QAbstractItemView::SelectRows);
	m_sequenceTable->setSelectionMode(QAbstractItemView::SingleSelection);

	connect(m_sequenceTable->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
			&CatalogSequencesPage::sequenceTable_currentRowChanged);
	connect(m_model, &SequenceModel::modelReset,
			[this] () { selectedSequenceChanged({}); });

	retranslateUi();
}

void CatalogSequencesPage::retranslateUi()
{
}

void CatalogSequencesPage::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
{
	m_catalog = cat;
	m_model->setCatalog(cat);
	m_sequenceTable->resizeColumnsToContents();
}

void CatalogSequencesPage::setNamespaceFilter(NamespaceFilter filter)
{
	m_model->setNamespaceFilter(filter);
}

void CatalogSequencesPage::sequenceTable_currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{
	if (current.row() != previous.row()) {
		if (current.isValid()) {
			auto source_index = m_sortFilterProxy->mapToSource(current);
			auto proc = m_model->sequence(source_index.row());

			selectedSequenceChanged(proc);
		}
		else
			selectedSequenceChanged({});
	}
}

void CatalogSequencesPage::selectedSequenceChanged(const std::optional<PgSequence> &seq)
{
	updateSqlTab(seq);
}

void CatalogSequencesPage::updateSqlTab(const std::optional<PgSequence> &seq)
{
	if (!seq.has_value()) {
		m_definitionView->clear();
		return;
	}
	QString create_sql = seq->createSql();

	m_definitionView->setPlainText(create_sql);
}
