<?php

use App\Services\System\BackupManagementService;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Storage;
use League\Flysystem\UnableToCreateDirectory;

beforeEach(function () {
    Cache::flush();
    $this->service = app(BackupManagementService::class);
});

test('checkRequirements returns ok shape with binary status', function () {
    $result = $this->service->checkRequirements();

    expect($result)->toHaveKey('status');
    expect($result['status'])->toBeBool();

    if (isset($result['binary'])) {
        expect($result['binary'])->toBeIn(['pg_dump', 'mysqldump']);
    }
});

test('testConnection on local disk succeeds', function () {
    // Storage::fake may fail in Docker containers with restricted permissions
    try {
        Storage::fake('local');
    } catch (UnableToCreateDirectory $e) {
        $this->markTestSkipped('Cannot create fake disk in this environment: '.$e->getMessage());
    }
    Config::set('backup.backup.destination.disks', ['local']);

    $result = $this->service->testConnection();

    expect($result['success'])->toBeTrue();
    expect($result['message'])->toContain('Successfully');
});

test('parseBytes round-trips through formatBytes for whole units', function () {
    $ref = new ReflectionMethod(BackupManagementService::class, 'parseBytes');
    $ref->setAccessible(true);

    expect($ref->invoke($this->service, '1 KB'))->toBe(1024.0);
    expect($ref->invoke($this->service, '1 MB'))->toBe(1048576.0);
    expect($ref->invoke($this->service, '2 GB'))->toBe(2.0 * 1024 * 1024 * 1024);
    expect($ref->invoke($this->service, '512 B'))->toBe(512.0);
});

test('parseBytes returns raw float when no unit suffix', function () {
    $ref = new ReflectionMethod(BackupManagementService::class, 'parseBytes');
    $ref->setAccessible(true);

    expect($ref->invoke($this->service, '4096'))->toBe(4096.0);
});

test('parseBytes ignores unknown units', function () {
    $ref = new ReflectionMethod(BackupManagementService::class, 'parseBytes');
    $ref->setAccessible(true);

    expect($ref->invoke($this->service, '10 XB'))->toBe(10.0);
});

test('parseBytes handles fractional values', function () {
    $ref = new ReflectionMethod(BackupManagementService::class, 'parseBytes');
    $ref->setAccessible(true);

    expect($ref->invoke($this->service, '1.5 KB'))->toBe(1536.0);
});

test('formatBytes private helper renders KB/MB/GB units', function () {
    $ref = new ReflectionMethod(BackupManagementService::class, 'formatBytes');
    $ref->setAccessible(true);

    expect($ref->invoke($this->service, 1024))->toBe('1 KB');
    expect($ref->invoke($this->service, 1024 * 1024))->toBe('1 MB');
    expect($ref->invoke($this->service, 1024 * 1024 * 1024))->toBe('1 GB');
});
