#ifndef CONNECTIONLISTMODEL_H
#define CONNECTIONLISTMODEL_H

#include <vector>
#include <memory>

#include <QAbstractListModel>

#include "ConnectionConfig.h"
#include <optional>
#include <variant>
#include <QVector>

#include "sqlite/SQLiteConnection.h"

class ConnectionTreeModel : public QAbstractItemModel {
	Q_OBJECT
public:
	enum Columns {
		Name,
		Host,
		Port,
		User,
		DbName,

		ColCount
	};

    ConnectionTreeModel(QObject *parent, SQLiteConnection &db);

	void load();

	QVariant data(const QModelIndex &index, int role) const override;

//	Qt::ItemFlags flags(const QModelIndex &index) const override;

	QVariant headerData(int section, Qt::Orientation orientation,
		int role = Qt::DisplayRole) const override;

	QModelIndex index(int row, int column,
		const QModelIndex &parent = QModelIndex()) const override;

	QModelIndex parent(const QModelIndex &index) const override;

	int rowCount(const QModelIndex &parent = QModelIndex()) const override;

	int columnCount(const QModelIndex &parent = QModelIndex()) const override;

	bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;

	/** Matches cc to the list by looking at its uuid.
	 *
	 * If it is not in the list it is added. If the uuid is in the list that entry is updated.
	 * If the group has been changed it is moved to the right group.
	 * In both cases the data is also directly written to long term storage.
	 */
	void save(const QString &group, const ConnectionConfig &cc);
	/** Save changed config, group is not allowed to change
	 */
	void save(const ConnectionConfig &cc);
    void clearAllPasswords();
	/// Create a new group in the DB and place in the tree
    int addGroup(const QString &group_name);
    void removeGroup(int row);
	int findGroup(int conngroup_id) const;

	static ConnectionConfig* getConfigFromModelIndex(QModelIndex index);

	static ConnectionGroup* getGroupFromModelIndex(QModelIndex index);
private:
	using Groups = QVector<std::shared_ptr<ConnectionGroup>>;

    SQLiteConnection &m_db;
	Groups m_groups;

	/// Finds the connection with the specified uuid and returns
	/// { group_index, connection_index }
	std::tuple<int, int> findConfig(const QUuid uuid) const;
	int findGroup(const QString &name) const;

    void saveToDb(const ConnectionConfig &cc);

    void loadGroups();
    void loadConnections();
    void loadConnectionParameters(ConnectionConfig &cc);
	// QAbstractItemModel interface
public:
	virtual Qt::DropActions supportedDropActions() const override;
	virtual Qt::DropActions supportedDragActions() const override;
	virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
//	virtual bool insertRows(int row, int count, const QModelIndex &parent) override;
//	virtual bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override;
	virtual QStringList mimeTypes() const override;
	virtual QMimeData *mimeData(const QModelIndexList &indexes) const override;
	virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
};

#endif // CONNECTIONLISTMODEL_H
