<?php
namespace Tests\Unit\Domain\Settings;

use PHPUnit\Framework\TestCase;
use Domain\Settings\SettingsRepository;

class SettingsRepositoryTest extends TestCase
{
    public function testCanBeInstantiated(): void
    {
        $repository = new SettingsRepository();
        $this->assertInstanceOf(SettingsRepository::class, $repository);
    }

    public function testHasSaveSettingsMethod(): void
    {
        $this->assertTrue(method_exists(SettingsRepository::class, 'saveSettings'));
    }

    public function testHasGetSettingsMethod(): void
    {
        $this->assertTrue(method_exists(SettingsRepository::class, 'getSettings'));
    }

    public function testAllSettingsReturnsAssociativeArray(): void
    {
        $mockDb = $this->createMock(\medoo::class);

        $mockDb->expects($this->once())
            ->method('select')
            ->with('pp_settings', '*')
            ->willReturn([
                ['param' => 'firm_name', 'value' => 'Test Shop'],
                ['param' => 'contact_email', 'value' => 'test@example.com'],
                ['param' => 'ssl', 'value' => '1'],
            ]);

        $service = new SettingsRepository($mockDb);
        $settings = $service->allSettings(true);

        $this->assertIsArray($settings);
        $this->assertEquals('Test Shop', $settings['firm_name']);
        $this->assertEquals('test@example.com', $settings['contact_email']);
        $this->assertEquals('1', $settings['ssl']);
        $this->assertCount(3, $settings);
    }

    public function testAllSettingsReturnsEmptyArrayWhenNoSettings(): void
    {
        $mockDb = $this->createMock(\medoo::class);

        $mockDb->expects($this->once())
            ->method('select')
            ->with('pp_settings', '*')
            ->willReturn([]);

        $service = new SettingsRepository($mockDb);
        $settings = $service->allSettings(true);

        $this->assertIsArray($settings);
        $this->assertEmpty($settings);
    }

    public function testAllSettingsHandlesNullFromDb(): void
    {
        $mockDb = $this->createMock(\medoo::class);

        $mockDb->expects($this->once())
            ->method('select')
            ->with('pp_settings', '*')
            ->willReturn(null);

        $service = new SettingsRepository($mockDb);
        $settings = $service->allSettings(true);

        $this->assertIsArray($settings);
        $this->assertEmpty($settings);
    }

    public function testGetSingleValueReturnsCorrectParam(): void
    {
        $mockDb = $this->createMock(\medoo::class);

        $mockDb->expects($this->once())
            ->method('get')
            ->with('pp_settings', 'value', ['param' => 'contact_email'])
            ->willReturn('test@example.com');

        $service = new SettingsRepository($mockDb);
        $value = $service->getSingleValue('contact_email');

        $this->assertEquals('test@example.com', $value);
    }

    public function testGetSingleValueUsesParamNotHardcoded(): void
    {
        $mockDb = $this->createMock(\medoo::class);

        // Kluczowy test: sprawdza ze param NIE jest hardcoded na 'firm_name'
        $mockDb->expects($this->once())
            ->method('get')
            ->with('pp_settings', 'value', ['param' => 'ssl'])
            ->willReturn('1');

        $service = new SettingsRepository($mockDb);
        $value = $service->getSingleValue('ssl');

        $this->assertEquals('1', $value);
    }

    public function testGetSingleValueReturnsEmptyStringWhenNotFound(): void
    {
        $mockDb = $this->createMock(\medoo::class);

        $mockDb->expects($this->once())
            ->method('get')
            ->with('pp_settings', 'value', ['param' => 'nonexistent'])
            ->willReturn(null);

        $service = new SettingsRepository($mockDb);
        $value = $service->getSingleValue('nonexistent');

        $this->assertEquals('', $value);
    }
}
