#include "importfolderdialog.h"

#include <QFileInfo>
#include <QLabel>
#include <QLineEdit>
#include <QVBoxLayout>

#include "exception.h"
#include "folderfilesfilterwidget.h"
#include "importfolderutils.h"
#include "vnotex.h"
#include <notebook/node.h>
#include <notebook/notebook.h>
#include <utils/pathutils.h>

using namespace vnotex;

ImportFolderDialog::ImportFolderDialog(Node *p_node, QWidget *p_parent)
    : ScrollDialog(p_parent), m_parentNode(p_node) {
  setupUI();

  m_filterWidget->getFolderPathEdit()->setFocus();
}

void ImportFolderDialog::setupUI() {
  auto widget = new QWidget(this);
  auto mainLayout = new QVBoxLayout(widget);
  setCentralWidget(widget);

  auto label =
      new QLabel(tr("Import folder into (%1).").arg(m_parentNode->fetchAbsolutePath()), widget);
  label->setWordWrap(true);
  mainLayout->addWidget(label);

  setupFolderFilesFilterWidget(widget);
  mainLayout->addWidget(m_filterWidget);

  setDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  setButtonEnabled(QDialogButtonBox::Ok, false);

  setWindowTitle(tr("Import Folder"));
}

void ImportFolderDialog::setupFolderFilesFilterWidget(QWidget *p_parent) {
  m_filterWidget = new FolderFilesFilterWidget(p_parent);
  connect(m_filterWidget, &FolderFilesFilterWidget::filesChanged, this,
          [this]() { validateInputs(); });
}

const QSharedPointer<Node> &ImportFolderDialog::getNewNode() const { return m_newNode; }

void ImportFolderDialog::acceptedButtonClicked() {
  if (isCompleted() || importFolder()) {
    accept();
  }
}

void ImportFolderDialog::validateInputs() {
  bool valid = true;
  QString msg;

  auto folder = m_filterWidget->getFolderPath();
  if (!QFileInfo::exists(folder) || !PathUtils::isLegalPath(folder)) {
    msg = tr("Please specify a valid folder to import.");
    valid = false;
  }

  setInformationText(msg, valid ? ScrollDialog::InformationLevel::Info
                                : ScrollDialog::InformationLevel::Error);
  setButtonEnabled(QDialogButtonBox::Ok, valid);
}

bool ImportFolderDialog::importFolder() {
  const auto folder = m_filterWidget->getFolderPath();
  auto nb = m_parentNode->getNotebook();
  if (PathUtils::pathContains(folder, m_parentNode->fetchAbsolutePath())) {
    // Avoid recursive import.
    auto msg = tr("Failed to add folder (%1) as node under (%2).")
                   .arg(folder, m_parentNode->fetchAbsolutePath());
    qCritical() << msg;
    setInformationText(msg, ScrollDialog::InformationLevel::Error);
    return false;
  }

  m_newNode = nullptr;
  try {
    m_newNode = nb->copyAsNode(m_parentNode, Node::Flag::Container, folder);
  } catch (Exception &p_e) {
    auto msg = tr("Failed to add folder (%1) as node (%2).").arg(folder, p_e.what());
    qCritical() << msg;
    setInformationText(msg, ScrollDialog::InformationLevel::Error);
    return false;
  }

  QString errMsg;
  ImportFolderUtils::importFolderContents(nb, m_newNode.data(), m_filterWidget->getSuffixes(),
                                          errMsg);

  emit nb->nodeUpdated(m_parentNode);

  if (!errMsg.isEmpty()) {
    qWarning() << errMsg;
    setInformationText(errMsg, ScrollDialog::InformationLevel::Error);
    completeButStay();
    return false;
  }

  return true;
}
