<?php

declare(strict_types=1);

require_once __DIR__ . '/../../vendor/autoload.php';

use App\Framework\Core\ValueObjects\EmailAddress;
use App\Framework\DI\DefaultContainer;
use App\Framework\GraphQL\Attributes\GraphQLField;
use App\Framework\GraphQL\Attributes\GraphQLQuery;
use App\Framework\GraphQL\Attributes\GraphQLType;
use App\Framework\GraphQL\Execution\QueryExecutor;
use App\Framework\GraphQL\Execution\QueryParser;
use App\Framework\GraphQL\Schema\SchemaBuilder;
use App\Framework\GraphQL\Schema\TypeResolver;

echo "Testing GraphQL System...\n\n";

// Test Classes
#[GraphQLType(description: 'A simple user')]
final readonly class TestUser
{
    public function __construct(
        #[GraphQLField(description: 'User ID')]
        public int $id,
        #[GraphQLField(description: 'User name')]
        public string $name,
        #[GraphQLField(description: 'User email')]
        public EmailAddress $email
    ) {
    }
}

#[GraphQLQuery]
final readonly class TestQueries
{
    public function __construct(
        private TestService $service
    ) {
    }

    #[GraphQLField(description: 'Get user by ID')]
    public function user(int $id): TestUser
    {
        return $this->service->getUser($id);
    }

    #[GraphQLField(description: 'List all users')]
    public function users(int $limit = 10): array
    {
        return $this->service->getUsers($limit);
    }
}

final readonly class TestService
{
    public function getUser(int $id): TestUser
    {
        return new TestUser(
            $id,
            "User {$id}",
            new EmailAddress("user{$id}@test.com")
        );
    }

    public function getUsers(int $limit): array
    {
        $users = [];
        for ($i = 1; $i <= $limit; $i++) {
            $users[] = new TestUser(
                $i,
                "User {$i}",
                new EmailAddress("user{$i}@test.com")
            );
        }

        return $users;
    }
}

// Setup DI Container
$container = new DefaultContainer();
$container->singleton(TestService::class, new TestService());

// Build Schema
echo "1. Building Schema...\n";
$typeResolver = new TypeResolver();
$schemaBuilder = new SchemaBuilder($container, $typeResolver);
$schema = $schemaBuilder->build([TestUser::class, TestQueries::class]);

echo "   ✓ Schema built successfully\n";
echo "   Types: " . count($schema->types) . "\n";
echo "   Queries: " . count($schema->queries) . "\n\n";

// Test SDL Generation
echo "2. Testing SDL Generation...\n";
$sdl = $schema->toSDL();
echo "   ✓ SDL generated\n";
echo "   Preview:\n";
echo substr($sdl, 0, 200) . "...\n\n";

// Test Query Parsing
echo "3. Testing Query Parser...\n";
$parser = new QueryParser();

$query1 = <<<'GRAPHQL'
{
    user(id: 1) {
        id
        name
        email
    }
}
GRAPHQL;

$parsed1 = $parser->parse($query1);
echo "   ✓ Simple query parsed\n";
echo "   Fields found: " . count($parsed1->fields) . "\n";
echo "   First field: " . $parsed1->fields[0]->name . "\n\n";

// Test Query Execution
echo "4. Testing Query Execution...\n";
$executor = new QueryExecutor($schema);

$result1 = $executor->execute($parsed1);
echo "   ✓ Query executed\n";
echo "   Success: " . ($result1->isSuccessful() ? 'Yes' : 'No') . "\n";
echo "   Data: " . json_encode($result1->data, JSON_PRETTY_PRINT) . "\n\n";

// Test with Variables
echo "5. Testing Query with Variables...\n";
$query2 = <<<'GRAPHQL'
query GetUser($userId: Int!) {
    user(id: $userId) {
        id
        name
    }
}
GRAPHQL;

$parsed2 = $parser->parse($query2);
$result2 = $executor->execute($parsed2, ['userId' => 42]);

echo "   ✓ Query with variables executed\n";
echo "   Success: " . ($result2->isSuccessful() ? 'Yes' : 'No') . "\n";
echo "   Data: " . json_encode($result2->data, JSON_PRETTY_PRINT) . "\n\n";

// Test List Query
echo "6. Testing List Query...\n";
$query3 = <<<'GRAPHQL'
{
    users(limit: 3) {
        id
        name
        email
    }
}
GRAPHQL;

$parsed3 = $parser->parse($query3);
$result3 = $executor->execute($parsed3);

echo "   ✓ List query executed\n";
echo "   Success: " . ($result3->isSuccessful() ? 'Yes' : 'No') . "\n";
echo "   Users returned: " . count($result3->data['users'] ?? []) . "\n\n";

echo "✅ All GraphQL System Tests Passed!\n";
