<?php

/**
 * Класс маршрута Flowaxy CMS
 * Представляет отдельный маршрут в системе
 *
 * @package Flowaxy\Core\Routing
 * @version 1.0.0 Alpha prerelease
 */

declare(strict_types=1);

namespace Flowaxy\Core\Routing;

class Route
{
    private array $methods;
    private string $path;
    private $handler;
    private array $middleware;
    private ?string $name;
    private array $params;
    private string $pattern;

    public function __construct(
        array $methods,
        string $path,
        $handler,
        array $options = []
    ) {
        $this->methods = array_map('strtoupper', $methods);
        $this->path = trim($path, '/');
        $this->handler = $handler;
        $this->middleware = $options['middleware'] ?? [];
        $this->name = $options['name'] ?? null;
        $this->params = $this->extractParams($path);
        $this->pattern = $this->pathToPattern($path);
    }

    public function getMethods(): array
    {
        return $this->methods;
    }

    public function getPath(): string
    {
        return $this->path;
    }

    public function getHandler()
    {
        return $this->handler;
    }

    public function getMiddleware(): array
    {
        return $this->middleware;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function getParams(): array
    {
        return $this->params;
    }

    public function getPattern(): string
    {
        return $this->pattern;
    }

    public function toArray(): array
    {
        return [
            'methods' => $this->methods,
            'path' => $this->path,
            'handler' => $this->handler,
            'middleware' => $this->middleware,
            'name' => $this->name,
            'params' => $this->params,
            'pattern' => $this->pattern,
        ];
    }

    private function extractParams(string $path): array
    {
        $params = [];
        if (preg_match_all('/\{([^}]+)\}/', $path, $matches)) {
            foreach ($matches[1] as $param) {
                $params[] = $param;
            }
        }
        return $params;
    }

    private function pathToPattern(string $path): string
    {
        $pattern = preg_replace('/\{([^}]+)\}/', '([^/]+)', $path);
        $pattern = str_replace('/', '\/', $pattern);
        return '/^\/' . $pattern . '$/';
    }
}
