<?php

declare(strict_types=1);

namespace App\Framework\GraphQL\Types;

/**
 * GraphQL scalar types
 *
 * Built-in scalars as defined in GraphQL spec
 */
enum GraphQLScalarType: string
{
    case INT = 'Int';
    case FLOAT = 'Float';
    case STRING = 'String';
    case BOOLEAN = 'Boolean';
    case ID = 'ID';

    /**
     * Get type name for schema definition
     */
    public function getTypeName(): string
    {
        return $this->value;
    }

    /**
     * Check if value is valid for this scalar type
     */
    public function isValidValue(mixed $value): bool
    {
        return match ($this) {
            self::INT => is_int($value),
            self::FLOAT => is_float($value) || is_int($value),
            self::STRING => is_string($value),
            self::BOOLEAN => is_bool($value),
            self::ID => is_string($value) || is_int($value),
        };
    }

    /**
     * Serialize value for output
     */
    public function serialize(mixed $value): mixed
    {
        return match ($this) {
            self::INT => (int) $value,
            self::FLOAT => (float) $value,
            self::STRING => (string) $value,
            self::BOOLEAN => (bool) $value,
            self::ID => (string) $value,
        };
    }

    /**
     * Parse value from input
     */
    public function parseValue(mixed $value): mixed
    {
        if (! $this->isValidValue($value)) {
            throw new \InvalidArgumentException(
                "Value is not a valid {$this->value}"
            );
        }

        return $this->serialize($value);
    }
}
