<?php

use classes\object_property;
use objects\selfserve_wash_sessions_o;

app_require('classes/object_property.php');
app_require('objects/selfserve_wash_sessions_o.php');

function selfserve_session_property(string $column, string $type, mixed $value): object_property
{
    $property = new object_property('selfserve_wash_sessions', -1, $column, $type);
    $property->set($value);

    return $property;
}

function selfserve_session_harness(
    string $status,
    ?string $completedAt,
    ?string $washStartedAt = '2026-04-28 10:00:00',
    ?string $machineStartTriggeredAt = null
): selfserve_wash_sessions_o {
    $session = (new ReflectionClass(selfserve_wash_sessions_o::class))->newInstanceWithoutConstructor();
    $session->status = selfserve_session_property('status', 'string', $status);
    $session->completed_at = selfserve_session_property('completed_at', 'datetime', $completedAt);
    $session->wash_started_at = selfserve_session_property('wash_started_at', 'datetime', $washStartedAt);
    $session->machine_start_triggered_at = selfserve_session_property('machine_start_triggered_at', 'datetime', $machineStartTriggeredAt);

    return $session;
}

it('treats terminal self-serve wash session statuses as closed', function (): void {
    expect(selfserve_wash_sessions_o::isTerminalStatus('COMPLETED'))->toBeTrue()
        ->and(selfserve_wash_sessions_o::isTerminalStatus('FORCE_STOPPED'))->toBeTrue()
        ->and(selfserve_wash_sessions_o::isTerminalStatus('MACHINE_STARTED'))->toBeFalse()
        ->and(selfserve_wash_sessions_o::terminalStatusSqlList())->toBe("'COMPLETED','FORCE_STOPPED'");

    expect(selfserve_session_harness('MACHINE_STARTED', null)->isOpen())->toBeTrue()
        ->and(selfserve_session_harness('COMPLETED', null)->isOpen())->toBeFalse()
        ->and(selfserve_session_harness('MACHINE_STARTED', '2026-04-28 10:30:00')->isOpen())->toBeFalse();
});

it('freezes elapsed self-serve wash minutes at completion time', function (): void {
    expect(selfserve_session_harness('COMPLETED', '2026-04-28 10:42:00')->getElapsedMinutes())->toBe(42)
        ->and(selfserve_session_harness('COMPLETED', '2026-04-28 10:35:00', null, '2026-04-28 10:05:00')->getElapsedMinutes())->toBe(30)
        ->and(selfserve_session_harness('COMPLETED', '2026-04-28 09:59:00')->getElapsedMinutes())->toBe(0);
});
