<?php

declare(strict_types=1);

require_once __DIR__.'/functions.inc.php';

function loadPreviousRecord(string $filename): ?array
{
	if (!is_file($filename)) {
		return null;
	}

	$lines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
	if ($lines === false || count($lines) < 2) {
		return null;
	}

	// The current record has already been appended, so the previous one is the line before it.
	$previous = json_decode($lines[count($lines) - 2], true);
	if (!is_array($previous)) {
		return null;
	}

	return $previous;
}

function levelsChanged(?array $previous, array $current): bool
{
	if ($previous === null) {
		return false;
	}

	foreach (['level1', 'level2', 'level3', 'level4'] as $name) {
		if (!array_key_exists($name, $previous) || (int) $previous[$name] !== (int) $current[$name]) {
			return true;
		}
	}

	return false;
}

function isValidLevelState(array $levels): bool
{
	$lowerLevelInactive = false;
	foreach (['level1', 'level2', 'level3', 'level4'] as $name) {
		if ((int) $levels[$name] === 0) {
			$lowerLevelInactive = true;
			continue;
		}

		if ($lowerLevelInactive) {
			return false;
		}
	}

	return true;
}

function calculateFilledPercent(array $levels): int
{
	$activeLevels = 0;
	foreach (['level1', 'level2', 'level3', 'level4'] as $name) {
		if ((int) $levels[$name] !== 1) {
			break;
		}

		$activeLevels++;
	}

	return $activeLevels * 25;
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
	header('Allow: POST');
	respondJson(405, [
		'success' => false,
		'error' => 'Method Not Allowed',
	]);
	exit;
}

$levels = [];
foreach (['level1', 'level2', 'level3', 'level4'] as $name) {
	if (!array_key_exists($name, $_POST)) {
		$levels[$name] = 0;
		continue;
	}

	if (is_array($_POST[$name])) {
		respondJson(400, [
			'success' => false,
			'error' => 'Invalid value for ' . $name,
		]);
		exit;
	}

	$value = trim((string) $_POST[$name]);
	if ($value !== '0' && $value !== '1') {
		respondJson(400, [
			'success' => false,
			'error' => 'Invalid value for ' . $name,
		]);
		exit;
	}

	$levels[$name] = (int) $value;
}

$record = [
	'timestamp' => date('c'),
	'level1' => (int) $levels['level1'],
	'level2' => (int) $levels['level2'],
	'level3' => (int) $levels['level3'],
	'level4' => (int) $levels['level4'],
];

$dataDir = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'data';
if (!is_dir($dataDir)) {
	if (!mkdir($dataDir, 0755, true) && !is_dir($dataDir)) {
		respondJson(500, [
			'success' => false,
			'error' => 'Failed to create data directory',
		]);
		exit;
	}
}

$filename = DATA_JSONL_FILEPATH;
$json = json_encode($record);
if ($json === false) {
	respondJson(500, [
		'success' => false,
		'error' => 'Failed to encode record',
	]);
	exit;
}

$written = file_put_contents($filename, $json . PHP_EOL, FILE_APPEND | LOCK_EX);
if ($written === false) {
	respondJson(500, [
		'success' => false,
		'error' => 'Failed to write log file',
	]);
	exit;
}

$previousRecord = loadPreviousRecord($filename);
if (levelsChanged($previousRecord, $record)) {
	// Notify only when the level state changed compared to the previous saved measurement.
	if (!isValidLevelState($record)) {
		notifyUsers(sprintf(
			'Chyba merania hladiny kondenzátu klimatizácie (level1=%d, level2=%d, level3=%d, level4=%d)',
			$record['level1'],
			$record['level2'],
			$record['level3'],
			$record['level4']
		));
	} else {
		$filledPercent = calculateFilledPercent($record);
		notifyUsers(sprintf('Nádržka kondenzu klimatizácie: %d%%', $filledPercent));
	}
}

respondJson(200, [
	'success' => true,
]);
