/*
 * Copyright (C) 2014-2024 CZ.NIC
 *
 * 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/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations including
 * the two.
 */

#include <QFont>
#include <QStringBuilder>

#include "src/datovka_shared/isds/type_description.h"
#include "src/models/users_model.h"

UsersModel::UsersModel(QObject *parent)
    : QAbstractTableModel(parent),
    m_users(),
    m_highlightedIsdsID()
{
}

int UsersModel::rowCount(const QModelIndex &parent) const
{
	if (parent.isValid()) {
		return 0;
	} else {
		return m_users.size();
	}
}

int UsersModel::columnCount(const QModelIndex &parent) const
{
	if (parent.isValid()) {
		return 0;
	} else {
		return MAX_COLNUM;
	}
}

QVariant UsersModel::data(const QModelIndex &index, int role) const
{
	const int row = index.row();
	const int col = index.column();
	if (Q_UNLIKELY((row < 0) || (row >= rowCount()))) {
		Q_ASSERT(0);
		return QVariant();
	}
	if (Q_UNLIKELY((col < 0) || (col >= columnCount()))) {
		Q_ASSERT(0);
		return QVariant();
	}

	switch (role) {
	case Qt::DisplayRole:
		switch (col) {
		case COL_GIV_NAMES:
			return m_users.at(row).personName().givenNames();
			break;
		case COL_LAST_NAME:
			return m_users.at(row).personName().lastName();
			break;
		case COL_USER_TYPE:
			return Isds::Description::descrUserType(m_users.at(row).userType()).toLower();
			break;
		default:
			Q_ASSERT(0);
			return QVariant();
			break;
		}
		break;
	case Qt::FontRole:
		if ((!m_highlightedIsdsID.isEmpty()) &&
		    (m_users.at(row).isdsID() == m_highlightedIsdsID)) {
			QFont boldFont;
			boldFont.setBold(true);
			return boldFont;
		}
		return QVariant();
		break;
	case Qt::AccessibleTextRole:
		switch (col) {
		case COL_GIV_NAMES:
		case COL_LAST_NAME:
		case COL_USER_TYPE:
			return headerData(index.column(), Qt::Horizontal).toString() +
			    QLatin1String(": ") + data(index, Qt::DisplayRole).toString();
			break;
		default:
			Q_ASSERT(0);
			return QVariant();
			break;
		}
		break;
	case ROLE_PROXYSORT:
		{
			const QString givNames = data(index.sibling(index.row(), COL_GIV_NAMES), Qt::DisplayRole).toString();
			const QString lastName = data(index.sibling(index.row(), COL_LAST_NAME), Qt::DisplayRole).toString();
			const QString userType = data(index.sibling(index.row(), COL_USER_TYPE), Qt::DisplayRole).toString();
			const QString space(" ");
			switch (col) {
			case COL_GIV_NAMES:
				return QString(givNames % space % lastName % space % userType);
				break;
			case COL_LAST_NAME:
				return QString(lastName % space % givNames % space % userType);
				break;
			case COL_USER_TYPE:
				return QString(userType % space % lastName % space % givNames);
				break;
			default:
				Q_ASSERT(0);
				return QVariant();
				break;
			}
		}
		break;
	default:
		return QVariant();
		break;
	}
}

Qt::ItemFlags UsersModel::flags(const QModelIndex &index) const
{
	return QAbstractTableModel::flags(index);
}

QVariant UsersModel::headerData(int section,
    Qt::Orientation orientation, int role) const
{
	if (Q_UNLIKELY(orientation == Qt::Vertical)) {
		return QVariant();
	}

	switch (role) {
	case Qt::DisplayRole:
		switch (section) {
		case COL_GIV_NAMES:
			return tr("Given Names");
			break;
		case COL_LAST_NAME:
			return tr("Last Name");
			break;
		case COL_USER_TYPE:
			return tr("User Type");
			break;
		default:
			Q_ASSERT(0);
			return QVariant();
			break;
		}
		break;
	default:
		return QVariant();
		break;
	}
}

void UsersModel::setContent(const QList<Isds::DbUserInfoExt2> &users,
    const QString &highlightedIsdsID)
{
	beginResetModel();

	m_users = users;
	m_highlightedIsdsID = highlightedIsdsID;

	endResetModel();
}

const Isds::DbUserInfoExt2 &UsersModel::contentAtRow(int row) const
{
	static const Isds::DbUserInfoExt2 userInfo;

	if (Q_UNLIKELY((row < 0) || (row >= rowCount()))) {
		Q_ASSERT(0);
		return userInfo;
	}

	return m_users.at(row);
}
