// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2020 Konrad Twardowski

// TODO: Bookmarks support

#include "filemonitor.h"

#include "../config.h"
#include "../uwidgets.h"

#include <QAbstractItemView>
#include <QCompleter>
#include <QDebug>
#include <QFileDialog>
#include <QFileSystemModel>
#include <QFormLayout>
#include <QLineEdit>
#include <QPushButton>

//======== FileMonitor public ========

FileMonitor::FileMonitor()
	: Trigger(i18n("File Monitor"), "folder", "file-monitor")
{
	setCheckInterval(1s);
}

bool FileMonitor::canActivateAction() {
	if (m_path.empty())
		return false;

	auto rule = static_cast<Rule>(m_ruleComboBox->currentIndex());

// TODO: update status after returning true
	switch (rule) {
		case Rule::Exists:    return exists();
		case Rule::NotExists: return ! exists();
		default:              return false;
	}
}

void FileMonitor::initContainerWidget() {

	//======== Combo Box ========

	m_ruleComboBox = new QComboBox();
	m_ruleComboBox->view()->setAlternatingRowColors(true);

	QIcon alignFallbackIcon = UWidgets::isIconThemeSupported() ? UWidgets::emptyIcon(m_ruleComboBox->iconSize()) : QIcon();

	m_ruleComboBox->addItem(
		QIcon::fromTheme("document-new", alignFallbackIcon),
		i18n("New File Created / Exists")
	);
	m_ruleComboBox->addItem(
		QIcon::fromTheme("edit-delete", alignFallbackIcon),
		i18n("Existing File Deleted")
	);

	m_ruleComboBox->setCurrentIndex(static_cast<int>(m_recentRule));

	connect(m_ruleComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]([[maybe_unused]] int index) {
		updateStatus();
	});

	//======== File Edit ========

	m_fileEdit = new QLineEdit(m_recentFile);
	m_fileEdit->setClearButtonEnabled(true);
// TODO: directory: m_fileEdit->setToolTip(i18n("A file or directory to monitor"));
	connect(m_fileEdit, &QLineEdit::textChanged, [this]([[maybe_unused]] const QString &text) {
		updateStatus();
	});

	auto *fileModel = new QFileSystemModel(this);
	fileModel->setOptions(QFileSystemModel::DontUseCustomDirectoryIcons | QFileSystemModel::DontWatchForChanges);
	fileModel->setRootPath(QDir::rootPath()); // does not work without it

// FIXME: won't complete a long(ish) path
	auto *fileCompleter = new QCompleter(this);
	fileCompleter->setModel(fileModel);
	fileCompleter->setCaseSensitivity(Qt::CaseInsensitive); // after setModel
	m_fileEdit->setCompleter(fileCompleter);

	//======== Push Button ========

	auto *selectButton = new QPushButton(i18n("Browse..."));

/* TODO:
	if (selectButton->style()->styleHint(QStyle::SH_DialogButtonBox_ButtonsHaveIcons))
		selectButton->setIcon(QIcon::fromTheme("folder"));
*/

	connect(selectButton, &QPushButton::clicked, [this]() {
		auto dialog = std::make_unique<QFileDialog>(m_fileEdit->window(), i18n("Select a file to monitor"));
		if (dialog->exec() == QFileDialog::Accepted) {
			m_fileEdit->setText(dialog->selectedFiles()[0]);
			//qDebug() << m_fileEdit->text();
		}
	});

	//======== Layout ========

	auto *fileLayout = UWidgets::newHBoxLayout({ m_fileEdit, selectButton }, 10_px);

	auto *layout = makeFormLayout();
	layout->addRow(i18n("File:"), fileLayout);
	layout->addRow(i18n("Rule:"), m_ruleComboBox);

	updateStatus();
}

void FileMonitor::readConfig() {
	QString group = configGroup();
	m_recentFile = Config::readString(group, "Recent File", m_recentFile);
	m_recentRule = static_cast<Rule>(
		Config::readInt(
			group, "Recent Rule",
			static_cast<int>(Rule::Exists), // default
			static_cast<int>(Rule::Exists), static_cast<int>(Rule::NotExists)
		)
	);
}

void FileMonitor::writeConfig() {
	if (m_fileEdit != nullptr)
		Config::writeString(configGroup(), "Recent File", m_fileEdit->text());

	if (m_ruleComboBox != nullptr)
		Config::writeInt(configGroup(), "Recent Rule", m_ruleComboBox->currentIndex());
}

//======== FileMonitor private ========

void FileMonitor::updateStatus() {
	//qDebug() << "FileMonitor::updateStatus()";

	auto rule = static_cast<Rule>(m_ruleComboBox->currentIndex());

	m_path = m_fileEdit->text()
		.trimmed()
		.toStdString();

	if (m_path.empty()) {
		setErrorStatus(i18n("No file selected"));
	}
	else if ((rule == Rule::Exists) && exists()) {
		setWarningStatus(i18n("File already exists"));
	}
	else if ((rule == Rule::NotExists) && ! exists()) {
		setWarningStatus(i18n("File already does not exist"));
	}
	else {
// FIXME: word wrap in InfoWidget
		auto name = QString::fromStdString(m_path.filename().string());
		setInfoStatus(
			i18n("Waiting for \"%0\"")
				.arg(Utils::trim(name, 30))
		);
// FIXME: auto restore default InfoWidget type if no status
	}
}
