<?php

declare(strict_types=1);

namespace Ekdos\Bootstrap;

use Ekdos\Auth\AuthController;
use Ekdos\Http\Middleware\RequireAuth;
use Ekdos\Http\Middleware\RequirePermission;
use Ekdos\Relay\CustomerInvoicesController;
use Ekdos\Relay\CustomersController;
use Ekdos\Relay\HoursController;
use Ekdos\Relay\InternalTasksController;
use Ekdos\Relay\InvoicesController;
use Ekdos\Relay\OffersController;
use Ekdos\Relay\OnlinePurchasesController;
use Ekdos\Relay\TicketsController;
use Ekdos\Support\Json;
use Ekdos\Users\Permission;
use Ekdos\Users\UserController;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\App;
use Slim\Routing\RouteCollectorProxy;

/**
 * Alle Routen der Anwendung.
 *
 * Anonym erreichbar sind nur die Gesundheitspruefung, die Anmeldung, die
 * Auth-Sonde /api/auth/me und der Cache-Hinweis von n8n. Alles andere haengt
 * hinter RequireAuth, rechtegebundene Aktionen zusaetzlich hinter RequirePermission.
 */
final class Routes
{
    public static function register(App $app): void
    {
        $app->group('/api', static function (RouteCollectorProxy $api): void {
            // ── Anonym ────────────────────────────────────────────────────
            // Die Oberflaeche prueft vor der Anmeldung, ob das Backend lebt.
            $api->get('/health', static fn (Request $r, Response $w): Response => Json::write($w, ['ok' => true, 'service' => 'ek-dos-web', 'time' => gmdate('c')]));

            $api->post('/auth/login', [AuthController::class, 'login']);
            $api->get('/auth/me', [AuthController::class, 'me']);
            $api->post('/auth/logout', [AuthController::class, 'logout']);

            // n8n meldet hierueber eine Ticketerstellung. Traegt entweder eine
            // Sitzung oder das geteilte Geheimnis; die Pruefung liegt im Controller.
            $api->post('/tickets/refresh', [TicketsController::class, 'refresh']);

            // ── Angemeldet ────────────────────────────────────────────────
            $api->group('', static function (RouteCollectorProxy $secure): void {
                $secure->post('/auth/refresh', [AuthController::class, 'refresh']);
                $secure->post('/auth/password', [AuthController::class, 'changeOwnPassword']);

                // Tickets
                $secure->get('/tickets', [TicketsController::class, 'index']);
                $secure->get('/tickets/digitale-akte', [TicketsController::class, 'digitalFile']);
                $secure->get('/tickets/servicebericht', [TicketsController::class, 'serviceReport']);
                $secure->post('/tickets/consultation', [TicketsController::class, 'consultation'])
                    ->add(new RequirePermission(Permission::InvoicesProcess));

                // Angebote
                $secure->get('/offers', [OffersController::class, 'index']);
                $secure->post('/offers', [OffersController::class, 'update']);
                $secure->delete('/offers', [OffersController::class, 'delete'])
                    ->add(new RequirePermission(Permission::OffersDelete));

                // Kundenstamm
                $secure->get('/customers', [CustomersController::class, 'index']);
                $secure->post('/customers', [CustomersController::class, 'create']);
                $secure->put('/customers', [CustomersController::class, 'update']);
                $secure->delete('/customers', [CustomersController::class, 'delete'])
                    ->add(new RequirePermission(Permission::CustomersDelete));
                $secure->get('/customers/digitale-akte', [CustomersController::class, 'digitalFile']);

                // Rechnungen eines Kunden und die Gesamtuebersicht
                $secure->get('/customer-invoices', [CustomerInvoicesController::class, 'index']);
                $secure->post('/customer-invoices', [CustomerInvoicesController::class, 'assign']);
                $secure->get('/customer-invoices/pdf', [CustomerInvoicesController::class, 'pdf']);
                $secure->post('/customer-invoices/sync', [CustomerInvoicesController::class, 'sync']);

                // Rechnungsablauf: anfertigen, pruefen, versenden
                $secure->get('/invoices-review', [InvoicesController::class, 'reviewList']);
                $secure->group('', static function (RouteCollectorProxy $invoices): void {
                    $invoices->get('/invoices-create', [InvoicesController::class, 'createList']);
                    $invoices->put('/invoices-create', [InvoicesController::class, 'completeCreateTask']);
                    $invoices->get('/invoices-create/digitale-akte', [InvoicesController::class, 'digitalFile']);
                    $invoices->get('/invoices-send', [InvoicesController::class, 'sendList']);
                    $invoices->post('/invoices-send', [InvoicesController::class, 'confirmSent']);
                })->add(new RequirePermission(Permission::InvoicesProcess));

                // Interne Aufgaben
                $secure->get('/internal-tasks', [InternalTasksController::class, 'index']);
                $secure->post('/internal-tasks', [InternalTasksController::class, 'create']);
                $secure->put('/internal-tasks', [InternalTasksController::class, 'complete']);
                $secure->patch('/internal-tasks', [InternalTasksController::class, 'edit']);
                $secure->delete('/internal-tasks', [InternalTasksController::class, 'delete'])
                    ->add(new RequirePermission(Permission::TasksDelete));

                // Online-Kaeufe
                $secure->get('/online-purchases', [OnlinePurchasesController::class, 'index']);
                $secure->post('/online-purchases', [OnlinePurchasesController::class, 'create'])
                    ->add(new RequirePermission(Permission::PurchasesCreate));
                $secure->put('/online-purchases', [OnlinePurchasesController::class, 'complete'])
                    ->add(new RequirePermission(Permission::PurchasesComplete));
                $secure->delete('/online-purchases', [OnlinePurchasesController::class, 'delete'])
                    ->add(new RequirePermission(Permission::PurchasesDelete));

                // Stundennachweise
                $secure->get('/hours', [HoursController::class, 'index']);

                // Benutzerverwaltung
                $secure->group('/users', static function (RouteCollectorProxy $users): void {
                    $users->get('', [UserController::class, 'index']);
                    $users->post('', [UserController::class, 'create']);
                    $users->get('/audit', [UserController::class, 'audit']);
                    $users->patch('/{id}', [UserController::class, 'update']);
                    $users->delete('/{id}', [UserController::class, 'delete']);
                })->add(new RequirePermission(Permission::UsersManage));
            })->add(new RequireAuth());
        });

        // Alles unterhalb von /api, was es nicht gibt, antwortet als JSON.
        // Statische Dateien beantwortet nginx, sie erreichen PHP nie.
        $app->any('/api/{path:.*}', static fn (Request $r, Response $w): Response => Json::error($w, 'Diese Schnittstelle gibt es nicht.', 404));
    }
}
