<?php

namespace App\Services\Docs;

use Illuminate\Routing\Route;
use Illuminate\Support\Facades\Route as RouteFacade;
use Illuminate\Support\Str;

class OpenApiRouteExporter
{
    public function exportFromFile(string $path): array
    {
        $base = [];
        if (is_file($path)) {
            $json = json_decode((string) file_get_contents($path), true);
            if (is_array($json)) {
                $base = $json;
            }
        }

        $base['paths'] = $base['paths'] ?? [];

        foreach (RouteFacade::getRoutes() as $route) {
            $this->mergeRoute($base['paths'], $route);
        }

        return $base;
    }

    private function mergeRoute(array &$paths, Route $route): void
    {
        if (!$this->isDocumentableRoute($route)) {
            return;
        }

        $uriRaw = ltrim($route->uri(), '/');
        if (str_starts_with($uriRaw, 'api/')) {
            $uri = '/' . $uriRaw;
        } elseif (str_starts_with($uriRaw, 'v1/')) {
            $uri = '/api/' . $uriRaw;
        } elseif ($uriRaw === 'v1') {
            $uri = '/api/v1';
        } else {
            return;
        }

        if (!str_starts_with($uri, '/api/v1')) {
            return;
        }

        $methods = array_diff($route->methods(), ['HEAD']);
        if (empty($methods)) {
            return;
        }

        $tag = $this->resolveTag($uri);
        foreach ($methods as $method) {
            $lower = strtolower($method);
            if (!isset($paths[$uri][$lower])) {
                $paths[$uri][$lower] = [
                    'tags' => [$tag],
                    'summary' => $this->summaryFromAction($route),
                    'responses' => [
                        '200' => [
                            'description' => 'OK',
                        ],
                    ],
                ];
            }
        }
    }

    private function isDocumentableRoute(Route $route): bool
    {
        $uri = ltrim($route->uri(), '/');
        if (!str_starts_with($uri, 'api/v1') && !str_starts_with($uri, 'v1/')) {
            return false;
        }

        $action = $route->getActionName();
        if (!is_string($action)) {
            return false;
        }

        if (str_contains($action, 'DocsController')) {
            return false;
        }

        if ($action === 'Closure') {
            return true;
        }

        return true;
    }

    private function resolveTag(string $uri): string
    {
        $trimmed = trim(str_replace('/api/v1', '', $uri), '/');
        if ($trimmed === '') {
            return 'api';
        }
        $segments = explode('/', $trimmed);
        $segment = $segments[0] ?: 'api';
        $secondary = $segments[1] ?? null;
        $normalized = Str::title(str_replace('-', ' ', $segment));
        $overrides = [
            'Whatsapp' => 'WhatsApp',
        ];

        if ($segment === 'finance' && $secondary === 'refunds') {
            return 'Refunds';
        }

        return $overrides[$normalized] ?? $normalized;
    }

    private function summaryFromAction(Route $route): string
    {
        $action = $route->getActionName();
        if (is_string($action) && str_contains($action, '@')) {
            [$controller, $method] = explode('@', $action, 2);
            $base = class_basename($controller);
            return $base . '::' . $method;
        }
        if (is_string($action)) {
            return $action;
        }
        return 'Endpoint';
    }
}
