<?php

namespace App\Controllers;

use App\Libraries\ApiKeyManager;

class ApiDocs extends BaseController
{
    public function index()
    {
        if ($redirect = $this->requireOrganizationContext()) {
            return $redirect;
        }

        $baseApiUrl = rtrim(site_url('api/v1'), '/');
        $endpoints = [
            [
                'method' => 'GET',
                'path' => '/audit?q={intervention_code|external_reference|tx_hash|anchor_hash}',
                'scope' => 'audit:read',
                'visibility' => lang('Backoffice.apiPublicVerify'),
                'summary' => 'Consulta publica de uma intervencao Quantum por codigo, referencia externa ou hash blockchain.',
                'example_path' => '/audit?q=MI-2026-0001',
            ],
            [
                'method' => 'GET',
                'path' => '/sites',
                'scope' => 'sites:read',
                'visibility' => lang('Backoffice.apiPrivateTenant'),
                'summary' => 'Lista os sites ou parques eolicos do tenant associado ao Bearer token.',
                'example_path' => '/sites',
            ],
            [
                'method' => 'POST',
                'path' => '/sites',
                'scope' => 'sites:write',
                'visibility' => lang('Backoffice.apiPrivateTenant'),
                'summary' => 'Cria um site Quantum com codigo unico, localizacao e estado operacional.',
                'example_path' => '/sites',
                'request_body' => [
                    'name' => 'Wind Farm Atlantic',
                    'site_code' => 'WF-PT-001',
                    'site_type' => 'wind_farm',
                    'country_code' => 'PT',
                    'region' => 'Viana do Castelo',
                    'location' => 'Viana do Castelo, Portugal',
                    'status' => 'active',
                ],
            ],
            [
                'method' => 'GET',
                'path' => '/turbines?site_id={id}',
                'scope' => 'turbines:read',
                'visibility' => lang('Backoffice.apiPrivateTenant'),
                'summary' => 'Lista turbinas, opcionalmente filtradas por site_id.',
                'example_path' => '/turbines?site_id=1',
            ],
            [
                'method' => 'POST',
                'path' => '/turbines',
                'scope' => 'turbines:write',
                'visibility' => lang('Backoffice.apiPrivateTenant'),
                'summary' => 'Cria uma turbina ligada a um site do mesmo tenant.',
                'example_path' => '/turbines',
                'request_body' => [
                    'site_id' => 1,
                    'turbine_code' => 'WT-PT-001',
                    'name' => 'Turbina Norte 01',
                    'manufacturer' => 'Vestas',
                    'model' => 'V136',
                    'rated_power_kw' => 4200,
                    'status' => 'active',
                ],
            ],
            [
                'method' => 'POST',
                'path' => '/maintenance/preview',
                'scope' => 'maintenance:write',
                'visibility' => lang('Backoffice.apiPrivateTenant'),
                'summary' => 'Valida a intervencao antes da criacao definitiva e devolve um resumo operativo.',
                'example_path' => '/maintenance/preview',
                'request_body' => [
                    'site_id' => 1,
                    'turbine_id' => 1,
                    'title' => 'Inspecao trimestral',
                    'intervention_type' => 'inspection',
                    'maintenance_mode' => 'scheduled',
                    'priority' => 'medium',
                    'status' => 'planned',
                    'external_reference' => 'ERP-2026-0001',
                ],
            ],
            [
                'method' => 'GET',
                'path' => '/maintenance?status=planned&site_id={id}',
                'scope' => 'maintenance:read',
                'visibility' => lang('Backoffice.apiPrivateTenant'),
                'summary' => 'Lista intervencoes do tenant e aceita filtros por estado, site e turbina.',
                'example_path' => '/maintenance?status=planned',
            ],
            [
                'method' => 'GET',
                'path' => '/maintenance/{intervention_code}',
                'scope' => 'maintenance:read',
                'visibility' => lang('Backoffice.apiPrivateTenant'),
                'summary' => 'Obtem detalhe da intervencao, eventos, anexos e transacoes blockchain.',
                'example_path' => '/maintenance/MI-2026-0001',
            ],
            [
                'method' => 'POST',
                'path' => '/maintenance',
                'scope' => 'maintenance:write',
                'visibility' => lang('Backoffice.apiPrivateTenant'),
                'summary' => 'Cria uma intervencao de manutencao no tenant autenticado.',
                'example_path' => '/maintenance',
                'request_body' => [
                    'site_id' => 1,
                    'turbine_id' => 1,
                    'title' => 'Substituicao de sensor de vibracao',
                    'description' => 'Aberta pelo sistema externo de manutencao.',
                    'intervention_type' => 'corrective',
                    'maintenance_mode' => 'corrective',
                    'priority' => 'high',
                    'status' => 'planned',
                    'reported_at' => '2026-06-15 09:30:00',
                    'external_reference' => 'CMMS-48219',
                ],
            ],
            [
                'method' => 'GET',
                'path' => '/blockchain?intervention_code={code}',
                'scope' => 'blockchain:read',
                'visibility' => lang('Backoffice.apiPrivateTenant'),
                'summary' => 'Lista anchors e transacoes blockchain associadas a intervencoes.',
                'example_path' => '/blockchain',
            ],
        ];

        foreach ($endpoints as &$endpoint) {
            $endpoint['example'] = $baseApiUrl . $endpoint['example_path'];
            $endpoint['code_samples'] = $this->buildCodeSamples(
                $endpoint['method'],
                $endpoint['example'],
                $endpoint['request_body'] ?? null,
                $endpoint['visibility'] !== lang('Backoffice.apiPublicVerify')
            );
        }
        unset($endpoint);

        $onboardingSteps = [
            [
                'title' => 'Criar o site',
                'summary' => 'Regista o parque eolico ou site operacional que vai conter as turbinas e as intervencoes.',
                'method' => 'POST',
                'path' => '/sites',
                'code_samples' => $this->buildCodeSamples('POST', $baseApiUrl . '/sites', [
                    'name' => 'Wind Farm Atlantic',
                    'site_code' => 'WF-PT-001',
                    'site_type' => 'wind_farm',
                    'country_code' => 'PT',
                    'region' => 'Viana do Castelo',
                    'location' => 'Viana do Castelo, Portugal',
                    'status' => 'active',
                ], true),
            ],
            [
                'title' => 'Registar a turbina',
                'summary' => 'Cria a turbina e liga-a ao site atraves de `site_id`.',
                'method' => 'POST',
                'path' => '/turbines',
                'code_samples' => $this->buildCodeSamples('POST', $baseApiUrl . '/turbines', [
                    'site_id' => 1,
                    'turbine_code' => 'WT-PT-001',
                    'name' => 'Turbina Norte 01',
                    'manufacturer' => 'Vestas',
                    'model' => 'V136',
                    'rated_power_kw' => 4200,
                    'status' => 'active',
                ], true),
            ],
            [
                'title' => 'Fazer preview da intervencao',
                'summary' => 'Valida o enquadramento da intervencao antes de a gravar definitivamente.',
                'method' => 'POST',
                'path' => '/maintenance/preview',
                'code_samples' => $this->buildCodeSamples('POST', $baseApiUrl . '/maintenance/preview', [
                    'site_id' => 1,
                    'turbine_id' => 1,
                    'title' => 'Inspecao trimestral',
                    'intervention_type' => 'inspection',
                    'maintenance_mode' => 'scheduled',
                    'priority' => 'medium',
                    'status' => 'planned',
                    'external_reference' => 'ERP-2026-0001',
                ], true),
            ],
            [
                'title' => 'Criar a intervencao',
                'summary' => 'Abre a intervencao com tipo, prioridade e referencia externa.',
                'method' => 'POST',
                'path' => '/maintenance',
                'code_samples' => $this->buildCodeSamples('POST', $baseApiUrl . '/maintenance', [
                    'site_id' => 1,
                    'turbine_id' => 1,
                    'title' => 'Substituicao de sensor de vibracao',
                    'description' => 'Aberta pelo sistema externo de manutencao.',
                    'intervention_type' => 'corrective',
                    'maintenance_mode' => 'corrective',
                    'priority' => 'high',
                    'status' => 'planned',
                    'reported_at' => '2026-06-15 09:30:00',
                    'external_reference' => 'CMMS-48219',
                ], true),
            ],
            [
                'title' => 'Consultar blockchain',
                'summary' => 'Lista os anchors blockchain ligados a intervencoes existentes.',
                'method' => 'GET',
                'path' => '/blockchain',
                'code_samples' => $this->buildCodeSamples('GET', $baseApiUrl . '/blockchain', null, true),
            ],
        ];

        return view('api_docs/index', [
            'title' => lang('Backoffice.menuApiDocs'),
            'active' => 'api_docs',
            'baseApiUrl' => $baseApiUrl,
            'availableScopes' => array_merge(['*'], ApiKeyManager::PUBLIC_SCOPES),
            'privateExample' => $this->buildCodeSamples('GET', $baseApiUrl . '/sites', null, true),
            'privateHeaders' => [
                'Authorization: Bearer <api_key>',
                'Accept: application/json',
                'Content-Type: application/json',
            ],
            'onboardingSteps' => $onboardingSteps,
            'endpoints' => $endpoints,
        ]);
    }

    private function buildCodeSamples(string $method, string $url, ?array $body = null, bool $requiresAuth = true): array
    {
        $headerLines = ["'Accept: application/json'"];
        $fetchHeaders = ["'Accept': 'application/json'"];
        $pythonHeaders = ["'Accept': 'application/json'"];
        $phpHeaders = ["'Accept: application/json'"];
        $javaHeaders = ['.header("Accept", "application/json")'];

        if ($requiresAuth) {
            $headerLines[] = "'Authorization: Bearer <api_key>'";
            $fetchHeaders[] = "'Authorization': 'Bearer <api_key>'";
            $pythonHeaders[] = "'Authorization': 'Bearer <api_key>'";
            $phpHeaders[] = "'Authorization: Bearer <api_key>'";
            $javaHeaders[] = '.header("Authorization", "Bearer <api_key>")';
        }

        if ($body !== null) {
            $headerLines[] = "'Content-Type: application/json'";
            $fetchHeaders[] = "'Content-Type': 'application/json'";
            $pythonHeaders[] = "'Content-Type': 'application/json'";
            $phpHeaders[] = "'Content-Type: application/json'";
            $javaHeaders[] = '.header("Content-Type", "application/json")';
        }

        $curl = ['curl -X ' . $method . ' "' . $url . '"'];
        foreach ($headerLines as $header) {
            $curl[] = '  -H ' . $header;
        }
        if ($body !== null) {
            $curl[] = "  -d '" . str_replace("'", "\\'", json_encode($body, JSON_UNESCAPED_SLASHES)) . "'";
        }

        $javascript = [
            "fetch('" . $url . "', {",
            "  method: '" . $method . "',",
            '  headers: {',
            '    ' . implode(",\n    ", $fetchHeaders),
            '  },',
        ];
        if ($body !== null) {
            $javascript[] = '  body: JSON.stringify(' . json_encode($body, JSON_UNESCAPED_SLASHES) . '),';
        }
        $javascript[] = '})';
        $javascript[] = '  .then((response) => response.json())';
        $javascript[] = '  .then((data) => console.log(data));';

        $python = [
            'import requests',
            '',
            "url = '" . $url . "'",
            'headers = {',
            '    ' . implode(",\n    ", $pythonHeaders),
            '}',
        ];
        if ($body !== null) {
            $python[] = 'payload = ' . json_encode($body, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
            $python[] = '';
            $python[] = 'response = requests.' . strtolower($method) . '(url, headers=headers, json=payload)';
        } else {
            $python[] = '';
            $python[] = 'response = requests.' . strtolower($method) . '(url, headers=headers)';
        }
        $python[] = 'print(response.json())';

        $php = [
            '<?php',
            '',
            '$ch = curl_init();',
            "curl_setopt(\$ch, CURLOPT_URL, '" . $url . "');",
            'curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);',
            "curl_setopt(\$ch, CURLOPT_CUSTOMREQUEST, '" . $method . "');",
            'curl_setopt($ch, CURLOPT_HTTPHEADER, [',
            '    ' . implode(",\n    ", $phpHeaders),
            ']);',
        ];
        if ($body !== null) {
            $php[] = 'curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(' . var_export($body, true) . '));';
        }
        $php[] = '';
        $php[] = '$response = curl_exec($ch);';
        $php[] = 'curl_close($ch);';
        $php[] = 'echo $response;';

        $java = [
            'import java.net.URI;',
            'import java.net.http.HttpClient;',
            'import java.net.http.HttpRequest;',
            'import java.net.http.HttpResponse;',
            '',
            'HttpRequest.Builder builder = HttpRequest.newBuilder()',
            '    .uri(URI.create("' . $url . '"))',
            '    ' . implode("\n    ", $javaHeaders),
        ];
        if ($body !== null) {
            $java[] = '    .method("' . $method . '", HttpRequest.BodyPublishers.ofString("""';
            $java[] = json_encode($body, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
            $java[] = '    """))';
        } elseif ($method === 'GET') {
            $java[] = '    .GET()';
        } else {
            $java[] = '    .method("' . $method . '", HttpRequest.BodyPublishers.noBody())';
        }
        $java[] = '    ;';
        $java[] = '';
        $java[] = 'HttpResponse<String> response = HttpClient.newHttpClient()';
        $java[] = '    .send(builder.build(), HttpResponse.BodyHandlers.ofString());';
        $java[] = 'System.out.println(response.body());';

        return [
            'curl' => implode(" \\\n", $curl),
            'javascript' => implode("\n", $javascript),
            'python' => implode("\n", $python),
            'php' => implode("\n", $php),
            'java' => implode("\n", $java),
        ];
    }
}
