/* GUI_PlaylistGeneratorPreferences.cpp, (Created on 29.03.2025) */

/* Copyright (C) 2011-2025 Michael Lugmair
 *
 * This file is part of Sayonara Player
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "GUI_PlaylistGeneratorPreferences.h"
#include "Gui/Preferences/ui_GUI_PlaylistGeneratorPreferences.h"

#include "Components/LibraryManagement/LibraryManager.h"
#include "Components/SmartPlaylists/SmartPlaylist.h"
#include "Gui/PlaylistGenerator/PlaylistGeneratorConfigurator.h"
#include "Utils/Language/Language.h"

#include "Utils/Logger/Logger.h"

#include <QListWidgetItem>

namespace
{
	constexpr const auto IdRole = Qt::UserRole + 1;

	void runActionOnCurrentItem(QListWidget* listWidget, const std::function<void(Spid)>& callback)
	{
		auto* item = listWidget->currentItem();
		if(!item)
		{
			return;
		}

		bool ok = false;
		if(const auto id = item->data(IdRole).toInt(&ok); (id >= 0) && ok)
		{
			callback(Spid{id});
		}

		spLog(Log::Warning, __FUNCTION__) << "Data cannot be converted isOk?" << ok;
	}
}

struct GUI_PlaylistGeneratorPreferences::Private
{
	PlaylistGeneratorConfigurator playlistGeneratorConfigurator;
	SmartPlaylistManager* smartPlaylistManager;

	explicit Private(SmartPlaylistManager* smartPlaylistManager, Library::Manager* libraryManager, QWidget* parent) :
		playlistGeneratorConfigurator{smartPlaylistManager, libraryManager, parent},
		smartPlaylistManager(smartPlaylistManager) {}

	QList<Spid> toDelete;
	QList<Spid> toAdd;
};

GUI_PlaylistGeneratorPreferences::GUI_PlaylistGeneratorPreferences(
	SmartPlaylistManager* smartPlaylistManager, Library::Manager* libraryManager, const QString& identifier) :
	Preferences::Base(identifier),
	m{Pimpl::make<Private>(smartPlaylistManager, libraryManager, this)} {}

GUI_PlaylistGeneratorPreferences::~GUI_PlaylistGeneratorPreferences() = default;

QString GUI_PlaylistGeneratorPreferences::actionName() const
{
	return Lang::get(Lang::SmartPlaylists);
}

bool GUI_PlaylistGeneratorPreferences::commit()
{
	for(const auto& aboutToBeDeleted: qAsConst(m->toDelete))
	{
		m->smartPlaylistManager->deletePlaylist(aboutToBeDeleted);
	}

	m->toAdd.clear();
	m->toDelete.clear();

	return true;
}

void GUI_PlaylistGeneratorPreferences::revert()
{
	ui->listWidget->clear();

	for(const auto& alreadyAdded: qAsConst(m->toAdd))
	{
		m->smartPlaylistManager->deletePlaylist(alreadyAdded);
	}

	m->toAdd.clear();
	m->toDelete.clear();

	populateList();
}

void GUI_PlaylistGeneratorPreferences::populateList()
{
	const auto generators = m->smartPlaylistManager->smartPlaylists();
	for(const auto& generator: generators)
	{
		const auto id = generator->id();
		auto* item = new QListWidgetItem(generator->name());
		item->setData(IdRole, id);

		if(!m->toDelete.contains(Spid{id}))
		{
			ui->listWidget->addItem(item);
		}
	}
}

void GUI_PlaylistGeneratorPreferences::initUi()
{
	ui = std::make_unique<Ui::GUI_PlaylistGeneratorPreferences>();
	ui->setupUi(this);

	connect(ui->btnAdd, &QPushButton::clicked, this, &GUI_PlaylistGeneratorPreferences::newClicked);
	connect(ui->btnEdit, &QPushButton::clicked, this, &GUI_PlaylistGeneratorPreferences::editClicked);
	connect(ui->btnRemove, &QPushButton::clicked, this, &GUI_PlaylistGeneratorPreferences::removeClicked);
}

void GUI_PlaylistGeneratorPreferences::retranslate()
{
	ui->btnAdd->setText(Lang::get(Lang::Add));
	ui->btnEdit->setText(Lang::get(Lang::Edit));
	ui->btnRemove->setText(Lang::get(Lang::Remove));
}

void GUI_PlaylistGeneratorPreferences::newClicked()
{
	const auto spid = m->playlistGeneratorConfigurator.createGenerator();
	if(spid.id >= 0)
	{
		m->toAdd << spid;
		populateList();
	}
}

void GUI_PlaylistGeneratorPreferences::editClicked()
{
	runActionOnCurrentItem(ui->listWidget, [this](const auto id) {
		m->playlistGeneratorConfigurator.editGenerator(id);
	});
}

void GUI_PlaylistGeneratorPreferences::removeClicked()
{
	spLog(Log::Info, this) << "remove cliced";

	runActionOnCurrentItem(ui->listWidget, [this](const auto id) {
		m->toDelete << Spid{id};

		auto* item = ui->listWidget->takeItem(ui->listWidget->currentRow());
		delete item;

		spLog(Log::Info, this) << "remove success";
	});
}
