<?php

declare(strict_types=1);

use App\Framework\MagicLinks\TokenAction;

describe('TokenAction Value Object', function () {
    it('creates valid action', function () {
        $action = new TokenAction('email_verification');

        expect($action->name)->toBe('email_verification');
        expect((string) $action)->toBe('email_verification');
    });

    it('allows lowercase letters and underscores', function () {
        $validActions = [
            'email_verification',
            'password_reset',
            'document_access',
            'user_invitation',
            'simple',
            'with_multiple_underscores',
        ];

        foreach ($validActions as $actionName) {
            $action = new TokenAction($actionName);
            expect($action->name)->toBe($actionName);
        }
    });

    it('rejects empty name', function () {
        expect(fn() => new TokenAction(''))
            ->toThrow(\InvalidArgumentException::class, 'Action name cannot be empty');
    });

    it('rejects uppercase letters', function () {
        expect(fn() => new TokenAction('EmailVerification'))
            ->toThrow(\InvalidArgumentException::class, 'Action name must contain only lowercase letters and underscores');
    });

    it('rejects numbers', function () {
        expect(fn() => new TokenAction('action123'))
            ->toThrow(\InvalidArgumentException::class, 'Action name must contain only lowercase letters and underscores');
    });

    it('rejects hyphens', function () {
        expect(fn() => new TokenAction('email-verification'))
            ->toThrow(\InvalidArgumentException::class, 'Action name must contain only lowercase letters and underscores');
    });

    it('rejects spaces', function () {
        expect(fn() => new TokenAction('email verification'))
            ->toThrow(\InvalidArgumentException::class, 'Action name must contain only lowercase letters and underscores');
    });

    it('rejects special characters', function () {
        $invalidActions = ['action@test', 'action.test', 'action!', 'action#', 'action$'];

        foreach ($invalidActions as $actionName) {
            expect(fn() => new TokenAction($actionName))
                ->toThrow(\InvalidArgumentException::class);
        }
    });

    it('compares actions correctly', function () {
        $action1 = new TokenAction('email_verification');
        $action2 = new TokenAction('email_verification');
        $action3 = new TokenAction('password_reset');

        expect($action1->equals($action2))->toBeTrue();
        expect($action1->equals($action3))->toBeFalse();
    });

    it('converts to string', function () {
        $action = new TokenAction('document_access');

        expect($action->__toString())->toBe('document_access');
        expect((string) $action)->toBe('document_access');
    });
});
