<?php
/*
 * Copyright 2026 Alessandro Chiapparini <sprint_planer_web@chiapparini.org>
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * See the LICENSE file in the project root for the full license text.
 */

declare(strict_types=1);

namespace App\Tests\Repositories;

use App\Repositories\AppSettingsRepository;
use App\Tests\TestCase;

/**
 * Phase 18: app_settings KV store. The migration seeds
 * task_status_enabled='0', so the boolean reader has a known starting point.
 */
final class AppSettingsRepositoryTest extends TestCase
{
    public function testSeededFlagDefaultsToOff(): void
    {
        $pdo  = $this->makeDb();
        $repo = new AppSettingsRepository($pdo);

        $this->assertSame('0', $repo->get('task_status_enabled'));
        $this->assertFalse($repo->getBool('task_status_enabled', false));
    }

    public function testSetReturnsBeforeAndAfter(): void
    {
        $pdo  = $this->makeDb();
        $repo = new AppSettingsRepository($pdo);

        $r = $repo->set('task_status_enabled', '1');
        $this->assertSame('0', $r['before']);
        $this->assertSame('1', $r['after']);
        $this->assertTrue($repo->getBool('task_status_enabled'));
    }

    public function testSetWithSameValueIsRecognisedAsNoop(): void
    {
        $pdo  = $this->makeDb();
        $repo = new AppSettingsRepository($pdo);

        $r = $repo->set('task_status_enabled', '0');
        $this->assertSame('0', $r['before']);
        $this->assertSame('0', $r['after']);
    }

    public function testGetReturnsDefaultForUnknownKey(): void
    {
        $pdo  = $this->makeDb();
        $repo = new AppSettingsRepository($pdo);

        $this->assertNull($repo->get('does_not_exist'));
        $this->assertSame('fallback', $repo->get('does_not_exist', 'fallback'));
        $this->assertFalse($repo->getBool('does_not_exist'));
        $this->assertTrue($repo->getBool('does_not_exist', true));
    }

    public function testInsertNewKeyOnFirstWrite(): void
    {
        $pdo  = $this->makeDb();
        $repo = new AppSettingsRepository($pdo);

        $r = $repo->set('new_flag', '1');
        $this->assertNull($r['before']);
        $this->assertSame('1', $r['after']);
        $this->assertSame('1', $repo->get('new_flag'));
    }

    public function testGetIntReadsNumericStringsAndFallsBackOnMissing(): void
    {
        $pdo  = $this->makeDb();
        $repo = new AppSettingsRepository($pdo);

        $this->assertSame(10, $repo->getInt('assignment_slider_max', 10));

        $repo->set('assignment_slider_max', '20');
        $this->assertSame(20, $repo->getInt('assignment_slider_max', 10));

        $repo->set('garbage_value', 'not-a-number');
        $this->assertSame(7, $repo->getInt('garbage_value', 7));
    }
}
