<?php

declare(strict_types=1);

use App\Framework\MagicLinks\Actions\ActionResult;
use App\Framework\MagicLinks\ValueObjects\ActionResultData;
use App\Framework\MagicLinks\ValueObjects\ErrorCollection;

describe('ActionResult', function () {
    it('creates successful result', function () {
        $result = new ActionResult(
            success: true,
            message: 'Operation completed successfully'
        );

        expect($result->success)->toBeTrue();
        expect($result->message)->toBe('Operation completed successfully');
        expect($result->isSuccess())->toBeTrue();
        expect($result->hasErrors())->toBeFalse();
    });

    it('creates failed result', function () {
        $errors = ErrorCollection::fromArray(['Error 1', 'Error 2']);
        $result = new ActionResult(
            success: false,
            message: 'Operation failed',
            errors: $errors
        );

        expect($result->success)->toBeFalse();
        expect($result->message)->toBe('Operation failed');
        expect($result->isSuccess())->toBeFalse();
        expect($result->hasErrors())->toBeTrue();
    });

    it('creates success with data', function () {
        $data = ActionResultData::fromArray(['user_id' => 123, 'email' => 'test@example.com']);
        $result = new ActionResult(
            success: true,
            message: 'User created',
            data: $data
        );

        expect($result->success)->toBeTrue();
        expect($result->data)->toBe($data);
        expect($result->data->get('user_id'))->toBe(123);
    });

    it('creates success with redirect', function () {
        $result = new ActionResult(
            success: true,
            message: 'Redirecting...',
            redirectUrl: '/dashboard'
        );

        expect($result->hasRedirect())->toBeTrue();
        expect($result->redirectUrl)->toBe('/dashboard');
    });

    it('uses success factory method', function () {
        $result = ActionResult::success('Email verified');

        expect($result->isSuccess())->toBeTrue();
        expect($result->message)->toBe('Email verified');
        expect($result->hasErrors())->toBeFalse();
    });

    it('uses success factory with data', function () {
        $data = ActionResultData::fromArray(['verified' => true]);
        $result = ActionResult::success('Email verified', $data);

        expect($result->isSuccess())->toBeTrue();
        expect($result->data)->toBe($data);
    });

    it('uses success factory with redirect', function () {
        $result = ActionResult::success(
            'Login successful',
            redirectUrl: '/dashboard'
        );

        expect($result->isSuccess())->toBeTrue();
        expect($result->hasRedirect())->toBeTrue();
        expect($result->redirectUrl)->toBe('/dashboard');
    });

    it('uses failure factory method', function () {
        $result = ActionResult::failure('Invalid credentials');

        expect($result->isSuccess())->toBeFalse();
        expect($result->message)->toBe('Invalid credentials');
    });

    it('uses failure factory with errors', function () {
        $errors = ErrorCollection::fromArray(['Email is required', 'Password is too short']);
        $result = ActionResult::failure('Validation failed', $errors);

        expect($result->isSuccess())->toBeFalse();
        expect($result->hasErrors())->toBeTrue();
        expect($result->errors)->toBe($errors);
        expect($result->errors->count())->toBe(2);
    });

    it('defaults to empty data and errors', function () {
        $result = ActionResult::success('Success');

        expect($result->data->toArray())->toBeEmpty();
        expect($result->errors->isEmpty())->toBeTrue();
    });

    it('checks redirect correctly', function () {
        $withRedirect = ActionResult::success('Done', redirectUrl: '/home');
        $withoutRedirect = ActionResult::success('Done');

        expect($withRedirect->hasRedirect())->toBeTrue();
        expect($withoutRedirect->hasRedirect())->toBeFalse();
    });

    it('checks errors correctly', function () {
        $withErrors = ActionResult::failure('Failed', ErrorCollection::single('Error'));
        $withoutErrors = ActionResult::success('Success');

        expect($withErrors->hasErrors())->toBeTrue();
        expect($withoutErrors->hasErrors())->toBeFalse();
    });

    it('allows empty message', function () {
        $result = ActionResult::success();

        expect($result->message)->toBe('');
        expect($result->isSuccess())->toBeTrue();
    });

    it('combines success with all optional parameters', function () {
        $data = ActionResultData::fromArray(['id' => 1]);
        $result = ActionResult::success(
            'Created',
            $data,
            '/view/1'
        );

        expect($result->isSuccess())->toBeTrue();
        expect($result->message)->toBe('Created');
        expect($result->data)->toBe($data);
        expect($result->redirectUrl)->toBe('/view/1');
        expect($result->hasRedirect())->toBeTrue();
    });
});
