<?php

declare(strict_types=1);

use App\Framework\Attributes\ApiVersionAttribute;
use App\Framework\Http\Versioning\ApiVersion;

describe('ApiVersionAttribute', function () {
    it('constructs with string version', function () {
        $attribute = new ApiVersionAttribute('1.0.0');

        expect($attribute->version)->toBeInstanceOf(ApiVersion::class);
        expect($attribute->version->toString())->toBe('v1.0.0');
        expect($attribute->introducedIn)->toBeNull();
        expect($attribute->deprecatedIn)->toBeNull();
        expect($attribute->removedIn)->toBeNull();
    });

    it('constructs with ApiVersion object', function () {
        $version = ApiVersion::fromString('2.0.0');
        $attribute = new ApiVersionAttribute($version);

        expect($attribute->version)->toBe($version);
        expect($attribute->version->toString())->toBe('v2.0.0');
    });

    it('constructs with all parameters', function () {
        $attribute = new ApiVersionAttribute(
            version: '2.0.0',
            introducedIn: '2.0.0',
            deprecatedIn: '3.0.0',
            removedIn: '4.0.0'
        );

        expect($attribute->version->toString())->toBe('v2.0.0');
        expect($attribute->introducedIn)->toBe('2.0.0');
        expect($attribute->deprecatedIn)->toBe('3.0.0');
        expect($attribute->removedIn)->toBe('4.0.0');
    });

    it('returns false for isDeprecated when not deprecated', function () {
        $attribute = new ApiVersionAttribute('1.0.0');

        expect($attribute->isDeprecated())->toBeFalse();
    });

    it('returns true for isDeprecated when deprecated', function () {
        $attribute = new ApiVersionAttribute(
            version: '2.0.0',
            deprecatedIn: '3.0.0'
        );

        expect($attribute->isDeprecated())->toBeTrue();
    });

    it('returns false for isRemoved when not removed', function () {
        $attribute = new ApiVersionAttribute('1.0.0');

        expect($attribute->isRemoved())->toBeFalse();
    });

    it('returns true for isRemoved when removed', function () {
        $attribute = new ApiVersionAttribute(
            version: '2.0.0',
            removedIn: '4.0.0'
        );

        expect($attribute->isRemoved())->toBeTrue();
    });

    it('returns null for getDeprecatedVersion when not deprecated', function () {
        $attribute = new ApiVersionAttribute('1.0.0');

        expect($attribute->getDeprecatedVersion())->toBeNull();
    });

    it('returns ApiVersion for getDeprecatedVersion when deprecated', function () {
        $attribute = new ApiVersionAttribute(
            version: '2.0.0',
            deprecatedIn: '3.0.0'
        );

        $deprecatedVersion = $attribute->getDeprecatedVersion();
        expect($deprecatedVersion)->toBeInstanceOf(ApiVersion::class);
        expect($deprecatedVersion->toString())->toBe('v3.0.0');
    });

    it('returns null for getRemovedVersion when not removed', function () {
        $attribute = new ApiVersionAttribute('1.0.0');

        expect($attribute->getRemovedVersion())->toBeNull();
    });

    it('returns ApiVersion for getRemovedVersion when removed', function () {
        $attribute = new ApiVersionAttribute(
            version: '2.0.0',
            removedIn: '4.0.0'
        );

        $removedVersion = $attribute->getRemovedVersion();
        expect($removedVersion)->toBeInstanceOf(ApiVersion::class);
        expect($removedVersion->toString())->toBe('v4.0.0');
    });

    it('returns null for getIntroducedVersion when not specified', function () {
        $attribute = new ApiVersionAttribute('1.0.0');

        expect($attribute->getIntroducedVersion())->toBeNull();
    });

    it('returns ApiVersion for getIntroducedVersion when specified', function () {
        $attribute = new ApiVersionAttribute(
            version: '2.0.0',
            introducedIn: '2.0.0'
        );

        $introducedVersion = $attribute->getIntroducedVersion();
        expect($introducedVersion)->toBeInstanceOf(ApiVersion::class);
        expect($introducedVersion->toString())->toBe('v2.0.0');
    });

    it('handles version lifecycle', function () {
        $attribute = new ApiVersionAttribute(
            version: '2.0.0',
            introducedIn: '2.0.0',
            deprecatedIn: '3.0.0',
            removedIn: '4.0.0'
        );

        expect($attribute->getIntroducedVersion()->toString())->toBe('v2.0.0');
        expect($attribute->getDeprecatedVersion()->toString())->toBe('v3.0.0');
        expect($attribute->getRemovedVersion()->toString())->toBe('v4.0.0');
        expect($attribute->isDeprecated())->toBeTrue();
        expect($attribute->isRemoved())->toBeTrue();
    });
});
