<?php

use App\Services\System\ActivityFormatter;

test('getFriendlyModelName returns System for null', function () {
    expect(ActivityFormatter::getFriendlyModelName(null))->toBe('System');
});

test('getFriendlyModelName maps known classes', function () {
    expect(ActivityFormatter::getFriendlyModelName('App\\Models\\SystemSetting'))->toBe('System Config');
    expect(ActivityFormatter::getFriendlyModelName('App\\Models\\User'))->toBe('User Profile');
    expect(ActivityFormatter::getFriendlyModelName('App\\Models\\Role'))->toBe('Access Role');
    expect(ActivityFormatter::getFriendlyModelName('App\\Models\\Permission'))->toBe('Access Permission');
});

test('getFriendlyModelName headlines unknown class basename', function () {
    expect(ActivityFormatter::getFriendlyModelName('App\\Models\\OtherSetting'))->toBe('Other Setting');
});

test('getEventBadgeClass returns correct class per event', function (string $event, string $expected) {
    expect(ActivityFormatter::getEventBadgeClass($event))->toBe($expected);
})->with([
    ['created', 'text-bg-success'],
    ['updated', 'text-bg-warning'],
    ['deleted', 'text-bg-danger'],
    ['restored', 'text-bg-info'],
    ['login', 'text-bg-info'],
    ['logout', 'text-bg-secondary'],
    ['password_changed', 'text-bg-primary'],
    ['unknown_event', 'text-bg-theme-1'],
]);

test('getEventBadgeClass is case insensitive', function () {
    expect(ActivityFormatter::getEventBadgeClass('CREATED'))->toBe('text-bg-success');
    expect(ActivityFormatter::getEventBadgeClass('Login'))->toBe('text-bg-info');
});

test('getEventIcon returns correct icon per event', function (string $event, string $expected) {
    expect(ActivityFormatter::getEventIcon($event))->toBe($expected);
})->with([
    ['created', 'bi-plus-circle'],
    ['updated', 'bi-pencil-square'],
    ['deleted', 'bi-trash'],
    ['logout', 'bi-box-arrow-right'],
    ['unknown', 'bi-info-circle'],
]);

test('formatChanges on creation shows all non-sensitive fields', function () {
    $result = ActivityFormatter::formatChanges([
        'old' => [],
        'attributes' => ['name' => 'Jane', 'email' => 'j@x.com', 'password' => 'secret'],
    ]);

    expect($result)->toHaveCount(2);
    $fields = array_column($result, 'field');
    expect($fields)->toContain('Name');
    expect($fields)->toContain('Email');
    expect($fields)->not->toContain('Password');
});

test('formatChanges on update returns only changed fields', function () {
    $result = ActivityFormatter::formatChanges([
        'old' => ['name' => 'Old', 'email' => 'same@x.com'],
        'attributes' => ['name' => 'New', 'email' => 'same@x.com'],
    ]);

    expect($result)->toHaveCount(1);
    expect($result[0]['field'])->toBe('Name');
    expect($result[0]['old'])->toBe('Old');
    expect($result[0]['new'])->toBe('New');
});

test('formatChanges filters out sensitive fields like password and remember_token', function () {
    $result = ActivityFormatter::formatChanges([
        'old' => ['password' => 'a', 'remember_token' => 'b', '2fa_secret' => 'c', 'api_token' => 'd'],
        'attributes' => ['password' => 'a2', 'remember_token' => 'b2', '2fa_secret' => 'c2', 'api_token' => 'd2'],
    ]);

    expect($result)->toBeEmpty();
});

test('formatChanges formats null, bool, array, empty string', function () {
    $result = ActivityFormatter::formatChanges([
        'old' => [],
        'attributes' => [
            'a_null' => null,
            'a_bool_true' => true,
            'a_bool_false' => false,
            'a_array' => ['x' => 1],
            'a_empty' => '',
        ],
    ]);

    $byField = collect($result)->keyBy('field');

    expect($byField['A Null']['new'])->toBe('NULL');
    expect($byField['A Bool True']['new'])->toBe('TRUE');
    expect($byField['A Bool False']['new'])->toBe('FALSE');
    expect($byField['A Array']['new'])->toBe(json_encode(['x' => 1], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
    expect($byField['A Empty']['new'])->toBe('[empty]');
});

test('formatChanges truncates strings longer than 200 chars', function () {
    $long = str_repeat('x', 250);
    $result = ActivityFormatter::formatChanges([
        'old' => [],
        'attributes' => ['big' => $long],
    ]);

    expect($result[0]['new'])->toEndWith('...');
    expect(strlen($result[0]['new']))->toBe(200);
});
