#include "CatalogFunctionsPage.h"
#include "ResultTableModelUtil.h"
#include "CustomFilterSortModel.h"
#include "CustomDataRole.h"
#include "util/PgLabItemDelegate.h"
#include "catalog/models/ProcTableModel.h"
#include "widgets/SqlCodePreview.h"
#include <QApplication>
#include "util/PgLabTableView.h"
#include <QHeaderView>
#include <QVBoxLayout>
#include <QTabWidget>

CatalogFunctionsPage::CatalogFunctionsPage(QWidget *parent)
	: QSplitter(Qt::Horizontal, parent)
{
	// create widgets
	m_functionTable = new PgLabTableView(this);
	m_detailTabs = new QTabWidget(this);
	m_definitionView = new SqlCodePreview(this);

	// build widget tree
	// add top level widgets to splitter
	addWidget(m_functionTable);
	addWidget(m_detailTabs);

	// add widgets to detail tabs
	m_detailTabs->addTab(m_definitionView, "SQL");

//	auto mainLayout = new QVBoxLayout;
//	mainLayout->addWidget(m_functionTable);
//	setLayout(mainLayout);

	// Do further initialization of widgets and models
	m_model = new ProcTableModel(this);
	m_sortFilterProxy = new CustomFilterSortModel(this);
	m_sortFilterProxy->setSourceModel(m_model);
	m_functionTable->setModel(m_sortFilterProxy);
    m_functionTable->horizontalHeader()->setSortIndicator(0, Qt::AscendingOrder);
	m_functionTable->setSortingEnabled(true);
	m_functionTable->setSelectionBehavior(QAbstractItemView::SelectRows);
	m_functionTable->setSelectionMode(QAbstractItemView::SingleSelection);

	connect(m_functionTable->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
			&CatalogFunctionsPage::functionTable_currentRowChanged);
	connect(m_model, &ProcTableModel::modelReset, m_definitionView, &SqlCodePreview::clear);

	retranslateUi();
}

void CatalogFunctionsPage::retranslateUi()
{
	auto set_tabtext = [this] (QWidget *widget, QString translation) {
		m_detailTabs->setTabText(m_detailTabs->indexOf(widget), translation);
	};

	set_tabtext(m_definitionView, QApplication::translate("FunctionsPage", "SQL", nullptr));
}

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

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

void CatalogFunctionsPage::functionTable_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->proc(source_index.row());

			selectedProcChanged(proc);
		}
		else
			selectedProcChanged({});
	}
}

void CatalogFunctionsPage::selectedProcChanged(const std::optional<PgProc> &proc)
{
	updateSqlTab(proc);
}

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

	m_definitionView->setPlainText(create_sql);
}
