<?php

namespace Tests\Unit\SystemCore\Enums;

use Modules\SystemCore\App\Enums\OrderStatus;
use PHPUnit\Framework\TestCase;

class OrderStatusTest extends TestCase
{
    // ==========================================
    // Cases Tests
    // ==========================================

    public function test_all_expected_cases_exist(): void
    {
        $cases = OrderStatus::cases();

        $this->assertCount(9, $cases);
        $this->assertContains(OrderStatus::Draft, $cases);
        $this->assertContains(OrderStatus::Pending, $cases);
        $this->assertContains(OrderStatus::Confirmed, $cases);
        $this->assertContains(OrderStatus::Processing, $cases);
        $this->assertContains(OrderStatus::Shipped, $cases);
        $this->assertContains(OrderStatus::Delivered, $cases);
        $this->assertContains(OrderStatus::Completed, $cases);
        $this->assertContains(OrderStatus::Cancelled, $cases);
        $this->assertContains(OrderStatus::Refunded, $cases);
    }

    public function test_case_values_are_correct(): void
    {
        $this->assertEquals('draft', OrderStatus::Draft->value);
        $this->assertEquals('pending', OrderStatus::Pending->value);
        $this->assertEquals('confirmed', OrderStatus::Confirmed->value);
        $this->assertEquals('processing', OrderStatus::Processing->value);
        $this->assertEquals('shipped', OrderStatus::Shipped->value);
        $this->assertEquals('delivered', OrderStatus::Delivered->value);
        $this->assertEquals('completed', OrderStatus::Completed->value);
        $this->assertEquals('cancelled', OrderStatus::Cancelled->value);
        $this->assertEquals('refunded', OrderStatus::Refunded->value);
    }

    // ==========================================
    // Label Tests
    // ==========================================

    public function test_label_returns_correct_strings(): void
    {
        $this->assertEquals('Draft', OrderStatus::Draft->label());
        $this->assertEquals('Pending', OrderStatus::Pending->label());
        $this->assertEquals('Confirmed', OrderStatus::Confirmed->label());
        $this->assertEquals('Processing', OrderStatus::Processing->label());
        $this->assertEquals('Shipped', OrderStatus::Shipped->label());
        $this->assertEquals('Delivered', OrderStatus::Delivered->label());
        $this->assertEquals('Completed', OrderStatus::Completed->label());
        $this->assertEquals('Cancelled', OrderStatus::Cancelled->label());
        $this->assertEquals('Refunded', OrderStatus::Refunded->label());
    }

    // ==========================================
    // Color Tests
    // ==========================================

    public function test_color_returns_valid_bootstrap_class(): void
    {
        $validColors = ['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'light', 'dark'];

        foreach (OrderStatus::cases() as $case) {
            $this->assertContains($case->color(), $validColors, "Invalid color for {$case->name}");
        }
    }

    public function test_color_returns_secondary_for_draft(): void
    {
        $this->assertEquals('secondary', OrderStatus::Draft->color());
    }

    public function test_color_returns_warning_for_pending(): void
    {
        $this->assertEquals('warning', OrderStatus::Pending->color());
    }

    public function test_color_returns_success_for_completed(): void
    {
        $this->assertEquals('success', OrderStatus::Completed->color());
    }

    public function test_color_returns_success_for_delivered(): void
    {
        $this->assertEquals('success', OrderStatus::Delivered->color());
    }

    public function test_color_returns_danger_for_cancelled(): void
    {
        $this->assertEquals('danger', OrderStatus::Cancelled->color());
    }

    public function test_color_returns_dark_for_refunded(): void
    {
        $this->assertEquals('dark', OrderStatus::Refunded->color());
    }

    // ==========================================
    // TryFrom Tests
    // ==========================================

    public function test_try_from_returns_enum_for_valid_value(): void
    {
        $status = OrderStatus::tryFrom('confirmed');

        $this->assertInstanceOf(OrderStatus::class, $status);
        $this->assertEquals(OrderStatus::Confirmed, $status);
    }

    public function test_try_from_returns_null_for_invalid_value(): void
    {
        $status = OrderStatus::tryFrom('invalid_status');

        $this->assertNull($status);
    }
}
