<?php

declare(strict_types=1);

namespace Autogedal\FeedMonitor\Test\Unit\Model;

use Autogedal\FeedMonitor\Model\Clock;
use Autogedal\FeedMonitor\Model\StateRepository;

/**
 * StateRepository without a database, rows as the table would hold them.
 */
class InMemoryStateRepository extends StateRepository
{
    /** @var array<string, array<string, mixed>> */
    public array $rows = [];

    public function __construct(private readonly Clock $testClock)
    {
    }

    public function get(string $key): ?array
    {
        return $this->rows[$key] ?? null;
    }

    public function getOpenAlerts(): array
    {
        return array_values(array_filter($this->rows, static fn (array $row): bool => (int)$row['alert_open'] === 1));
    }

    public function save(string $key, array $data): void
    {
        $this->rows[$key] = array_merge($this->rows[$key] ?? [
            'monitor_key' => $key,
            'alert_open' => 0,
            'problem' => null,
            'message' => null,
            'first_detected_at' => null,
            'last_notified_at' => null,
            'recovery_pending' => 0,
            'allow_incomplete_until' => null,
            'watched_since' => null,
        ], $data, ['updated_at' => $this->testClock->format()]);
    }

    public function watchedSince(string $key): int
    {
        if (empty($this->rows[$key]['watched_since'])) {
            $this->save($key, ['watched_since' => $this->testClock->format()]);
        }

        return (int)strtotime($this->rows[$key]['watched_since'] . ' UTC');
    }

    public function allowIncomplete(string $key, int $hours = self::ALLOWANCE_HOURS): void
    {
        $this->save($key, ['allow_incomplete_until' => $this->testClock->format($this->testClock->now() + $hours * 3600)]);
    }

    public function consumeIncompleteAllowance(string $key): bool
    {
        $until = $this->rows[$key]['allow_incomplete_until'] ?? null;
        if ($until === null || $until < $this->testClock->format()) {
            return false;
        }
        $this->rows[$key]['allow_incomplete_until'] = null;

        return true;
    }
}
