#include "BatteryController.h"

#include <QDateTime>
#include <QDebug>

#include <bitset>

BatteryController::BatteryController(
	QObject *parent)
	: QObject{parent}
{}

BatteryController::~BatteryController()
{
}

int BatteryController::batteryIndex() const
{
	return batteryIndex_;
}

void BatteryController::setBatteryIndex(int index)
{
	if (batteryIndex_ == index)
		return;

	batteryIndex_ = index;
	emit batteryIndexChanged();
}

int BatteryController::chargeType() const
{
	return chargeType_;
}

void BatteryController::setChargeType(int type)
{
	if (chargeType_ == type)
		return;

	chargeType_ = type;
	emit chargeTypeChanged();
}

int BatteryController::workingMode() const
{
	return workingMode_;
}

void BatteryController::setWorkingMode(int mode)
{
	if (workingMode_ == mode)
		return;

	workingMode_ = mode;
	emit workingModeChanged();
}

QVariant BatteryController::controlVoltage() const
{
	return controlVoltage_;
}

void BatteryController::setControlVoltage(const QVariant& value)
{
	if (controlVoltage_ == value)
		return;

	controlVoltage_ = value;
	emit controlVoltageChanged();
}

QVariant BatteryController::controlCurrent() const
{
	return controlCurrent_;
}

void BatteryController::setControlCurrent(const QVariant& value)
{
	if (controlCurrent_ == value)
		return;

	controlCurrent_ = value;
	emit controlCurrentChanged();
}

QVariant BatteryController::controlTemperature() const
{
	return controlTemperature_;
}

void BatteryController::setControlTemperature(const QVariant& value)
{
	if (controlTemperature_ == value)
		return;

	controlTemperature_ = value;
	emit controlTemperatureChanged();
}

QVariant BatteryController::controlCapacity() const
{
	return controlCapacity_;
}

void BatteryController::setControlCapacity(const QVariant& value)
{
	if (controlCapacity_ == value)
		return;

	controlCapacity_ = value;
	emit controlCapacityChanged();
}

QVariant BatteryController::measuredVoltage() const
{
	return measuredVoltage_;
}

void BatteryController::setMeasuredVoltage(const QVariant& value)
{
	if (measuredVoltage_ == value)
		return;

	measuredVoltage_ = value;
	emit measuredVoltageChanged();
}

QVariant BatteryController::measuredCurrent() const
{
	return measuredCurrent_;
}

void BatteryController::setMeasuredCurrent(const QVariant& value)
{
	if (measuredCurrent_ == value)
		return;

	measuredCurrent_ = value;
	emit measuredCurrentChanged();
}

QVariant BatteryController::measuredTemperature() const
{
	return measuredTemperature_;
}

void BatteryController::setMeasuredTemperature(const QVariant& value)
{
	if (measuredTemperature_ == value)
		return;

	measuredTemperature_ = value;
	emit measuredTemperatureChanged();
}

QVariant BatteryController::measuredCapacity() const
{
	return measuredCapacity_;
}

void BatteryController::setMeasuredCapacity(const QVariant& value)
{
	if (measuredCapacity_ == value)
		return;

	measuredCapacity_ = value;
	emit measuredCapacityChanged();
}

QVariantList BatteryController::statuses() const
{
	return statuses_;
}

void BatteryController::setStatuses(const QVariantList& statuses)
{
	if (statuses_ == statuses)
		return;

	statuses_ = statuses;
	emit statusesChanged();
}

void BatteryController::addStatus(const quint16 status)
{
	// QString description;
	// auto appendDescription = [&description](const QString& subStatus)
	// {
	// 	if (!description.isEmpty())
	// 	{
	// 		description += ", ";
	// 	}
	// 	description += subStatus;
	// };

	QStringList descriptionList;
	auto appendDescription = [&descriptionList](const QString& subStatus)
	{
		descriptionList.append(subStatus);
	};

	std::bitset<16> descriptionBitset(status);
	if (descriptionBitset.test(0))
	{
		appendDescription("Ошибка Т датчика КП");
	}
	if (descriptionBitset.test(1))
	{
		appendDescription("Низкий разряд АКБ");
	}
	if (descriptionBitset.test(2))
	{
		appendDescription("Заряд завершен");
	}
	if (descriptionBitset.test(3))
	{
		appendDescription("Ошибка Т датчика УКПБ");
	}

	if (descriptionBitset.test(4))
	{
		appendDescription("Ток долго не снижается");
	}
	if (descriptionBitset.test(5))
	{
		appendDescription("Ошибка БПС3000");
	}
	if (descriptionBitset.test(6))
	{
		appendDescription("U менее 61.25 В");
	}
	if (descriptionBitset.test(7))
	{
		appendDescription("U выше нормы по КП");
	}


	if (descriptionBitset.test(8))
	{
		appendDescription("Останов первого заряда");
	}
	if (descriptionBitset.test(9))
	{
		appendDescription("Останов разряда");
	}
	if (descriptionBitset.test(10))
	{
		appendDescription("Останов второго заряда");
	}
	if (descriptionBitset.test(11))
	{
		appendDescription("Более 45 гр. С");
	}

	if (descriptionBitset.test(12))
	{
		appendDescription("Разночтение в токах");
	}

	if (descriptionList.isEmpty())
	{
		appendDescription("Штатный режим");
	}

	statuses_.clear();

	for (const auto& description: descriptionList)
	{
		QVariantMap statusMap;
		statusMap.insert("time", QDateTime::currentDateTime().toString("hh:mm:ss dd-MM-yyyy"));
		statusMap.insert("status", "0x" + QString::number(status, 16).toUpper().rightJustified(2, '0'));
		statusMap.insert("description", description);

		statuses_.append(statusMap);
	}

	emit statusesChanged();

	// if (statuses_.isEmpty() || statuses_.first().toMap()["status"] != statusMap["status"])
	// {
	// 	qDebug() << "Status:" << statusMap["status"].toString() << statusMap["description"].toString();
	// 	statuses_.prepend(statusMap);
	// 	emit statusesChanged();
	// }
}
