#include "addproducttypedialog.h"

#include "ui_addproducttypedialog.h"

#include "../sqlscript/sqlscript.h"

#include "../sqltreenode/sqltreenode.h"

#include "../colouredlineedit/colouredlineedit.h"

#include <QGridLayout>

#include <QPair>

AddProductTypeDialog::AddProductTypeDialog(
    const SqlTreeNode<QString> *sqlTreeNode, QWidget *parent, Qt::WindowFlags f)
    : QDialog(parent, f), m_ui(new Ui::AddProductTypeDialog) {
  m_ui->setupUi(this);
  setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
  initializeWidgetItems();
  createLineEditWidgets();
  configureConnections();
  configureTreeWidget();
  configureStandardText();
  showCase(sqlTreeNode);
}

AddProductTypeDialog::~AddProductTypeDialog() { delete m_ui; }

void AddProductTypeDialog::createLineEditWidgets() {
  m_currentTypeNameLineEdit = new ColouredLineEdit;
  m_ui->m_currentTypeNameLabel->setBuddy(m_currentTypeNameLineEdit);
  m_ui->m_interactionLayout->addWidget(m_currentTypeNameLineEdit, 1, 1, 1, 1);

  m_futureTypeNameLineEdit = new ColouredLineEdit;
  m_ui->m_futureTypeNameLabel->setBuddy(m_futureTypeNameLineEdit);
  m_ui->m_interactionLayout->addWidget(m_futureTypeNameLineEdit, 2, 1, 1, 1);
}

void AddProductTypeDialog::initializeWidgetItems() {
  m_commonTreeWidgetItem = m_ui->m_futureTreeWidget->topLevelItem(0);
  m_currentTreeWidgetItem = m_commonTreeWidgetItem->child(0);
  m_futureTreeWidgetItem = m_commonTreeWidgetItem->child(1);
}

void AddProductTypeDialog::configureConnections() {
  auto pairsLineEditTreeWidgetItem = {
      QPair(m_futureTypeNameLineEdit, m_futureTreeWidgetItem),
      QPair(m_currentTypeNameLineEdit, m_currentTreeWidgetItem)};
  using namespace std::placeholders;
  for (auto &pairs : pairsLineEditTreeWidgetItem)
    connect(pairs.first, &QLineEdit::textChanged, this,
            [pairs](const QString &text) {
              auto &[edit, item] = pairs;
              if (text.isEmpty())
                item->setText(m_textColumn, edit->placeholderText());
              else
                item->setText(m_textColumn, text);
            });
}

void AddProductTypeDialog::configureTreeWidget() {
  m_ui->m_futureTreeWidget->expandAll();
  m_ui->m_futureTreeWidget->setItemsExpandable(false);
}

void AddProductTypeDialog::configureStandardText() {
  m_futureTreeWidgetItem->setText(m_textColumn, tr("New products"));
  m_futureTypeNameLineEdit->setPlaceholderText(
      m_futureTreeWidgetItem->text(m_textColumn));

  m_currentTreeWidgetItem->setText(m_textColumn, tr("Existing products"));
  m_currentTypeNameLineEdit->setPlaceholderText(
      m_currentTreeWidgetItem->text(m_textColumn));
}

void AddProductTypeDialog::showCase(const SqlTreeNode<QString> *sqlTreeNode) {
  QString selectedNodeName = sqlTreeNode->data;
  QString topText = m_ui->m_topLabel->text();
  topText = topText.arg(selectedNodeName);
  m_ui->m_topLabel->setText(topText);

  bool hasNestedNodes = !sqlTreeNode->nestedNodes.empty();
  if (hasNestedNodes) {
    showGoodCase(std::move(selectedNodeName));
    return;
  }

  int productTypeId = int(sqlTreeNode->recordIdentifier);
  bool hasProducts = SqlScript::doesProductExist(productTypeId);
  if (!hasProducts) {
    showGoodCase(std::move(selectedNodeName));
    return;
  }
  showBadCase(std::move(selectedNodeName));
}

void AddProductTypeDialog::done(int resultCode) {
  if (QDialog::Accepted == resultCode) {
    foreach (auto *lineEdit, findChildren<ColouredLineEdit *>())
      if (!lineEdit->isHidden() && lineEdit->isEnabled() &&
          lineEdit->text().isEmpty()) {
        notifyInputError();
        QApplication::beep();
        return;
      }
  }
  QDialog::done(resultCode);
  return;
}

void AddProductTypeDialog::setHiddenBadCaseGroup(bool hidden) {
  m_ui->m_currentTypeNameLabel->setHidden(hidden);
  m_currentTypeNameLineEdit->setHidden(hidden);
  m_currentTreeWidgetItem->setHidden(hidden);
}

bool AddProductTypeDialog::lastCase() { return m_lastCase; }

QString AddProductTypeDialog::futureTypeName() {
  return m_futureTypeNameLineEdit->text();
}

QString AddProductTypeDialog::currentTypeName() {
  return m_currentTypeNameLineEdit->text();
}

void AddProductTypeDialog::setTopText(const QString &value) {
  m_ui->m_topLabel->setText(value);
}

void AddProductTypeDialog::showGoodCase(QString &&commonNodeName) {
  m_lastCase = true;
  setHiddenBadCaseGroup(m_lastCase);

  m_ui->m_stackedWidget->setCurrentWidget(m_ui->m_goodCasePage);
  m_commonTreeWidgetItem->setText(m_textColumn, commonNodeName);

  m_futureTypeNameLineEdit->setFocus();
}

void AddProductTypeDialog::showBadCase(QString &&commonNodeName) {
  m_lastCase = false;
  setHiddenBadCaseGroup(m_lastCase);

  m_ui->m_stackedWidget->setCurrentWidget(m_ui->m_badCasePage);
  m_commonTreeWidgetItem->setText(m_textColumn, commonNodeName);

  m_currentTypeNameLineEdit->setFocus();
}

void AddProductTypeDialog::notifyInputError() {
  foreach (auto *lineEdit, findChildren<ColouredLineEdit *>())
    if (lineEdit->isEnabled() && lineEdit->text().isEmpty())
      lineEdit->notice(Qt::red);
}
