#include "itemscrollbox.h"
#include "ui_relayscrollbox.h"
#include <QScrollArea>
#include <QScroller>
#include <QFrame>

ItemScrollBox::ItemScrollBox(QWidget *parent) :
	QWidget(parent),
	ui(new Ui::RelayScrollBox)
{
	ui->setupUi(this);
	
	ensureTabExists("All");
	ui->tabWidget->setCurrentIndex(0);
}

ItemScrollBox::~ItemScrollBox()
{
	delete ui;
}

void ItemScrollBox::addItem(std::weak_ptr<Item> item)
{
	if(auto workItem  = item.lock())
	{
		if(workItem->isHidden())
			return;

		// Add to "All" tab
		widgets_["All"].push_back(new ItemWidget(item, false));
		QWidget* allScrollContent = tabs_["All"].content;
		QLayout* layout = allScrollContent->layout();
		layout->removeItem(tabs_["All"].spacer);
		layout->addWidget(widgets_["All"].back());
		layout->addItem(tabs_["All"].spacer);
		connect(widgets_["All"].back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::deleteRequest);
		connect(widgets_["All"].back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::removeItem);
		
		addItemToTabs(item);
	}
}

void ItemScrollBox::addItemToTabs(std::weak_ptr<Item> item)
{
	if(auto workItem  = item.lock())
	{
		if(workItem->isHidden())
			return;

		QString groupName = workItem->getGroupName();
		if(groupName.isEmpty() || groupName != "All")
		{
			ensureTabExists(groupName);
			ItemWidget* groupWidget = new ItemWidget(item, true);
			widgets_[groupName].push_back(groupWidget);

			QWidget* scrollContent = tabs_[groupName].content;
			QLayout* groupLayout = scrollContent->layout();
			groupLayout->removeItem(tabs_[groupName].spacer);
			groupLayout->addWidget(groupWidget);
			groupLayout->addItem(tabs_[groupName].spacer);

			connect(groupWidget, &ItemWidget::deleteRequest, this, &ItemScrollBox::deleteRequest);
			connect(groupWidget, &ItemWidget::deleteRequest, this, &ItemScrollBox::removeItem);

			connect(widgets_[groupName].back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::deleteRequest);
			connect(widgets_[groupName].back(), &ItemWidget::deleteRequest, this, &ItemScrollBox::removeItem);
		}
	}
}

void ItemScrollBox::removeItem(const ItemData& item)
{
	QString key = "All";
	std::vector<ItemWidget*>& widgets = widgets_[key];
	for(unsigned i = 0; i < widgets.size(); i++)
	{
		if(widgets[i]->controles(item))
		{
			QWidget* tabContent = tabs_[key].content;
			if(tabContent)
			{
				QLayout* layout = tabContent->layout();
				if(layout)
					layout->removeWidget(widgets[i]);
			}
			delete widgets[i];
			widgets.erase(widgets.begin()+i);
			break;
		}
	}

	removeItemFromTabs(item);
	cleanupEmptyTabs();
}

void ItemScrollBox::removeItemFromTabs(const ItemData& item)
{
	for(const QString& key : widgets_.keys())
	{
		if(key == "All")
			continue;
		std::vector<ItemWidget*>& widgets = widgets_[key];
		for(unsigned i = 0; i < widgets.size(); i++)
		{
			if(widgets[i]->controles(item))
			{
				QWidget* tabContent = tabs_[key].content;
				if(tabContent)
				{
					QLayout* layout = tabContent->layout();
					if(layout)
						layout->removeWidget(widgets[i]);
				}
				delete widgets[i];
				widgets.erase(widgets.begin()+i);
				break;
			}
		}
	}

	cleanupEmptyTabs();
}


void ItemScrollBox::onItemUpdate(const ItemUpdateRequest& update)
{
	if(!update.changes.groupName)
		return;

	for(ItemWidget* widget : widgets_["All"])
	{
		if(widget->controles(update.payload))
		{
			qDebug()<<"ItemUpdate with group change for item"<<update.payload.getName()<<"type"<<update.type;
			std::weak_ptr<Item> item = widget->getItem();
			removeItemFromTabs(update.payload);
			addItemToTabs(item);
		}
	}
}

void ItemScrollBox::ensureTabExists(const QString& groupName)
{
	if(!tabs_.contains(groupName))
	{
		Tab tab;
		tab.scroller = new QScrollArea(ui->tabWidget);
		tab.scroller->setWidgetResizable(true);
		tab.scroller->setFrameShape(QFrame::NoFrame);
		tab.scroller->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
		QScroller::grabGesture(tab.scroller->viewport(), QScroller::LeftMouseButtonGesture);

		tab.content = new QWidget(tab.scroller);
		QVBoxLayout* scrollLayout = new QVBoxLayout(tab.content);
		scrollLayout->setContentsMargins(0, 0, 0, 0);
		tab.content->setLayout(scrollLayout);
		tab.content->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
		tab.scroller->setWidget(tab.content);

		tab.spacer = new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding);
		scrollLayout->addSpacerItem(tab.spacer);

		ui->tabWidget->addTab(tab.scroller, groupName);
		tabs_[groupName] = tab;

		if(groupName == pendingSelectedGroup_)
		{
			ui->tabWidget->setCurrentWidget(tab.scroller);
			pendingSelectedGroup_.clear();
		}
	}
}

void ItemScrollBox::cleanupEmptyTabs()
{
	for(auto it = tabs_.begin(); it != tabs_.end(); ++it)
	{
		QString groupName = it.key();
		if(groupName == "All")
			continue;

		qDebug()<<__func__<<it.value().content->layout()->count();

		if(it.value().content->layout()->count() <= 1)
		{
			int index = ui->tabWidget->indexOf(tabs_[groupName].scroller);
			if(index >= 0)
				ui->tabWidget->removeTab(index);
			Tab tab = tabs_.take(groupName);
			delete tab.content;
			delete tab.scroller;
			cleanupEmptyTabs();
			break;
		}
	}
}

void ItemScrollBox::store(QJsonObject& json) const
{
	QJsonObject itemScrollBoxJson;
	int currentIndex = ui->tabWidget->currentIndex();
	if(currentIndex >= 0)
	{
		QString selectedGroup = ui->tabWidget->tabText(currentIndex);
		itemScrollBoxJson["SelectedGroup"] = selectedGroup;
	}
	json["ItemScrollBox"] = itemScrollBoxJson;
}

void ItemScrollBox::load(const QJsonObject& json)
{
	QJsonObject itemScrollBoxJson = json["ItemScrollBox"].toObject();
	pendingSelectedGroup_ = itemScrollBoxJson["SelectedGroup"].toString();
}
