<?php

namespace Tests\Unit\Enums;

use App\Enums\PlatformEnum;
use Tests\TestCase;

class PlatformEnumTest extends TestCase
{
    public function test_enum_cases_have_correct_values(): void
    {
        $this->assertEquals('lemmy', PlatformEnum::LEMMY->value);
    }

    public function test_enum_cases_exist(): void
    {
        $cases = PlatformEnum::cases();

        $this->assertCount(1, $cases);
        $this->assertContains(PlatformEnum::LEMMY, $cases);
    }

    public function test_enum_names_are_correct(): void
    {
        $this->assertEquals('LEMMY', PlatformEnum::LEMMY->name);
    }

    public function test_can_create_enum_from_string(): void
    {
        $this->assertEquals(PlatformEnum::LEMMY, PlatformEnum::from('lemmy'));
    }

    public function test_try_from_with_valid_values(): void
    {
        $this->assertEquals(PlatformEnum::LEMMY, PlatformEnum::tryFrom('lemmy'));
    }

    public function test_try_from_with_invalid_value_returns_null(): void
    {
        $this->assertNull(PlatformEnum::tryFrom('reddit'));
        $this->assertNull(PlatformEnum::tryFrom('mastodon'));
        $this->assertNull(PlatformEnum::tryFrom(''));
        $this->assertNull(PlatformEnum::tryFrom('LEMMY')); // case sensitive
    }

    public function test_from_throws_exception_for_invalid_value(): void
    {
        $this->expectException(\ValueError::class);
        PlatformEnum::from('reddit');
    }

    public function test_enum_can_be_compared(): void
    {
        $lemmy1 = PlatformEnum::LEMMY;
        $lemmy2 = PlatformEnum::LEMMY;

        $this->assertTrue($lemmy1 === $lemmy2);
    }

    public function test_enum_can_be_used_in_match_expression(): void
    {
        $getDescription = function (PlatformEnum $platform): string {
            return match ($platform) {
                PlatformEnum::LEMMY => 'Lemmy is a federated link aggregator',
            };
        };

        $this->assertEquals('Lemmy is a federated link aggregator', $getDescription(PlatformEnum::LEMMY));
    }

    public function test_enum_can_be_used_in_switch_statement(): void
    {
        $platform = PlatformEnum::LEMMY;
        $result = '';

        switch ($platform) {
            case PlatformEnum::LEMMY:
                $result = 'lemmy platform';
                break;
        }

        $this->assertEquals('lemmy platform', $result);
    }

    public function test_enum_value_is_string_backed(): void
    {
        $this->assertIsString(PlatformEnum::LEMMY->value);
    }

    public function test_channel_label_returns_community_for_lemmy(): void
    {
        $this->assertEquals('Community', PlatformEnum::LEMMY->channelLabel());
    }

    public function test_channel_label_plural_returns_communities_for_lemmy(): void
    {
        $this->assertEquals('Communities', PlatformEnum::LEMMY->channelLabelPlural());
    }
}
