#include "CatalogTypesPage.h"
#include "ResultTableModelUtil.h"
#include "CustomFilterSortModel.h"
#include "CustomDataRole.h"
#include "util/PgLabItemDelegate.h"
#include "catalog/PgType.h"
#include "model/TypeSelectionItemModel.h"
#include "widgets/SqlCodePreview.h"
#include "util/PgLabTableView.h"
#include <optional>
#include <QHeaderView>

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

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

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

    connect(m_typeTable->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
            &CatalogTypesPage::typeTable_currentRowChanged);
    connect(m_model, &TypeModel::modelReset,
            [this] () { selectedTypeChanged({}); });

    retranslateUi();

}

void CatalogTypesPage::retranslateUi()
{
}

void CatalogTypesPage::setCatalog(std::shared_ptr<const PgDatabaseCatalog> cat)
{
    m_catalog = cat;
    m_model->setTypeList(cat->types());
    m_typeTable->resizeColumnsToContents();
}

void CatalogTypesPage::typeTable_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->typ(source_index.row());
            selectedTypeChanged(proc);
        }
        else
            selectedTypeChanged({});
    }
}

void CatalogTypesPage::selectedTypeChanged(const std::optional<PgType> &typ)
{
    updateSqlTab(typ);
}

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

    m_definitionView->setPlainText(create_sql);
}
