<?php

declare(strict_types=1);
umask(0077);

require_once __DIR__ . '/../app/Services/DB.php';
require_once __DIR__ . '/../app/Services/Migrations.php';
require_once __DIR__ . '/../app/Services/Ids.php';
require_once __DIR__ . '/../app/Services/IcadService.php';
require_once __DIR__ . '/../app/Services/DocumentsService.php';
require_once __DIR__ . '/../app/Services/Auth.php';
require_once __DIR__ . '/../app/Services/TrustedDeviceService.php';
require_once __DIR__ . '/../app/Services/PermissionService.php';
require_once __DIR__ . '/../app/Services/AuditService.php';
require_once __DIR__ . '/../app/Services/BackupService.php';
require_once __DIR__ . '/../app/Services/AppSettings.php';
require_once __DIR__ . '/../app/Services/InstallationService.php';
require_once __DIR__ . '/../app/Services/SystemHealthService.php';
require_once __DIR__ . '/../app/Services/NotificationService.php';
require_once __DIR__ . '/../app/Services/PrivacyService.php';
require_once __DIR__ . '/../app/Services/I18n.php';
require_once __DIR__ . '/../app/Services/PricingService.php';
require_once __DIR__ . '/../app/Services/ImageService.php';
require_once __DIR__ . '/../app/Services/PrivateMediaService.php';
require_once __DIR__ . '/../app/Services/SecurityService.php';
require_once __DIR__ . '/../app/Services/ExportService.php';
require_once __DIR__ . '/../app/Services/AssociationBrand.php';
require_once __DIR__ . '/../app/Services/GrantService.php';
require_once __DIR__ . '/../app/Services/StatisticsService.php';
require_once __DIR__ . '/../app/Services/LocationHistoryService.php';
require_once __DIR__ . '/../app/Services/GeoService.php';
require_once __DIR__ . '/../app/Services/Asm3Analyzer.php';
require_once __DIR__ . '/../app/Services/Asm3MigrationPlanner.php';
require_once __DIR__ . '/../app/Services/Asm3AnimalImporter.php';
require_once __DIR__ . '/../app/Services/Asm3ContactPlanner.php';
require_once __DIR__ . '/../app/Services/Asm3ContactImporter.php';
require_once __DIR__ . '/../app/Services/Asm3MovementImporter.php';
require_once __DIR__ . '/../app/Services/Asm3ClinicalImporter.php';
require_once __DIR__ . '/../app/Services/Asm3LitterImporter.php';
require_once __DIR__ . '/../app/Services/Asm3ResetService.php';
require_once __DIR__ . '/../app/Services/DemoDataService.php';
require_once __DIR__ . '/../app/Services/SpeciesService.php';
require_once __DIR__ . '/../app/Services/ShelterRoomService.php';
require_once __DIR__ . '/../app/Services/LabReferenceService.php';
require_once __DIR__ . '/../app/Services/InventoryService.php';
require_once __DIR__ . '/../app/Services/AgendaService.php';
require_once __DIR__ . '/../app/Services/CalendarFeedService.php';
require_once __DIR__ . '/../app/Services/GlobalSearchService.php';
require_once __DIR__ . '/../app/Controllers/AnimalsController.php';
require_once __DIR__ . '/../app/Controllers/DevController.php';
require_once __DIR__ . '/../app/Controllers/DashboardController.php';
require_once __DIR__ . '/../app/Controllers/AdminController.php';
require_once __DIR__ . '/../app/Controllers/AdoptionsController.php';
require_once __DIR__ . '/../app/Controllers/DirectoryController.php';
require_once __DIR__ . '/../app/Controllers/CareRoundsController.php';
require_once __DIR__ . '/../app/Controllers/DocumentsController.php';
require_once __DIR__ . '/../app/Controllers/AuthController.php';
require_once __DIR__ . '/../app/Controllers/SettingsController.php';
require_once __DIR__ . '/../app/Controllers/DeathController.php';
require_once __DIR__ . '/../app/Controllers/ProjectController.php';
require_once __DIR__ . '/../app/Controllers/GrantsController.php';
require_once __DIR__ . '/../app/Controllers/StatisticsController.php';
require_once __DIR__ . '/../app/Controllers/PlacementsController.php';
require_once __DIR__ . '/../app/Controllers/Asm3ImportController.php';
require_once __DIR__ . '/../app/Controllers/DewormingController.php';
require_once __DIR__ . '/../app/Controllers/MedicalDocumentsController.php';
require_once __DIR__ . '/../app/Controllers/PublicSiteController.php';
require_once __DIR__ . '/../app/Controllers/PrivacyController.php';
require_once __DIR__ . '/../app/Controllers/InventoryController.php';
require_once __DIR__ . '/../app/Controllers/AgendaController.php';
require_once __DIR__ . '/../app/Controllers/DevicesController.php';
require_once __DIR__ . '/../app/Controllers/SurgeriesController.php';
require_once __DIR__ . '/../app/Controllers/AccountingController.php';
require_once __DIR__ . '/../app/Controllers/SearchController.php';
require_once __DIR__ . '/../app/Views/_helpers.php';

function loadEnv(string $path): void
{
    if (!file_exists($path)) {
        return;
    }

    foreach (file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
        if (str_starts_with(trim($line), '#')) {
            continue;
        }
        [$name, $value] = array_map('trim', explode('=', $line, 2));
        if (!array_key_exists($name, $_ENV)) {
            putenv("$name=$value");
            $_ENV[$name] = $value;
        }
    }
}

loadEnv(__DIR__ . '/../.env');
$applicationLogDir = dirname(__DIR__) . '/storage/logs';
if (!is_dir($applicationLogDir)) {
    @mkdir($applicationLogDir, 0775, true);
}
if (is_dir($applicationLogDir) && is_writable($applicationLogDir)) {
    ini_set('log_errors', '1');
    ini_set('error_log', $applicationLogDir . '/php-errors.log');
}

if (PHP_SAPI !== 'cli' && is_file(dirname(__DIR__) . '/storage/maintenance.flag')) {
    http_response_code(503);
    header('Retry-After: 120');
    header('Content-Type: text/html; charset=utf-8');
    echo '<!doctype html><html lang="fr"><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>Maintenance — Globinours</title><body style="font:18px system-ui;max-width:700px;margin:12vh auto;padding:24px"><h1>Globinours fait une petite pause 🐾</h1><p>Une mise à jour sécurisée est en cours. Réessayez dans quelques instants.</p></body></html>';
    exit();
}

$bootstrapPath = rtrim((string) (parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/'), '/') ?: '/';
$bootstrapIssues = InstallationService::blockingRuntimeIssues();
if ($bootstrapIssues) {
    I18n::setLocale('fr');
    Auth::start();
    if ($bootstrapPath !== '/setup') {
        header('Location: /setup');
        exit();
    }
    AuthController::setupUnavailable(InstallationService::runtimeChecks(true));
    exit();
}

function render(string $view, array $vars = []): void
{
    extract($vars, EXTR_SKIP);
    $viewFile = __DIR__ . '/../app/Views/' . $view;
    require __DIR__ . '/../app/Views/layout.php';
}

Migrations::run(__DIR__ . '/../migrations');
PrivateMediaService::migrateLegacy();
SecurityService::hardenRuntimeFiles();
I18n::setLocale(AppSettings::get('app_language'));

$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) ?? '/';
$path = rtrim($path, '/') ?: '/';
Auth::start();
header_remove('X-Powered-By');
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
header('Referrer-Policy: strict-origin-when-cross-origin');
header('Permissions-Policy: camera=(self), geolocation=(self), microphone=()');
header(
    "Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https://tile.openstreetmap.org https://*.tile.openstreetmap.org; font-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; form-action 'self'; manifest-src 'self'; worker-src 'self'",
);
header('Cross-Origin-Opener-Policy: same-origin');
header('Cross-Origin-Resource-Policy: same-origin');
if (Auth::isSecureRequest()) {
    header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
}

if ($path === '/gestion') {
    header('Location: ' . (Auth::user() ? '/dashboard' : '/login?next=%2Fdashboard'));
    exit();
}
if (PublicSiteController::handles($path)) {
    PublicSiteController::dispatch($path);
    exit();
}

if ($path === '/auth/logo') {
    AuthController::logo();
    exit();
}
if ($path === '/pwa-icon-192.png') {
    AuthController::pwaIcon(192);
    exit();
}
if ($path === '/pwa-icon-512.png') {
    AuthController::pwaIcon(512);
    exit();
}
if ($path === '/setup') {
    AuthController::setup();
    exit();
}
if ($path === '/login') {
    AuthController::login();
    exit();
}
if ($path === '/logout') {
    AuthController::logout();
    exit();
}
if ($path === '/agenda/feed.ics') {
    AgendaController::feed();
    exit();
}
if (Auth::countUsers() === 0) {
    header('Location: /setup');
    exit();
}
if (!Auth::user()) {
    header('Location: /login?next=' . rawurlencode($_SERVER['REQUEST_URI'] ?? '/dashboard'));
    exit();
}
header('Cache-Control: private, no-store');
if ($path === '/account/devices') {
    DevicesController::index();
    exit();
}
if ($path === '/account/devices/revoke') {
    DevicesController::revoke();
    exit();
}
if ($path === '/account/devices/revoke-all') {
    DevicesController::revokeAll();
    exit();
}
if ($path === '/agenda/feed/regenerate') {
    AgendaController::regenerateFeed();
    exit();
}
if ($path === '/agenda/feed/revoke') {
    AgendaController::revokeFeed();
    exit();
}
if ($path === '/' && !PermissionService::can('dashboard')) {
    header('Location: ' . PermissionService::firstAllowedPath());
    exit();
}
PermissionService::enforce($path, (string) ($_SERVER['REQUEST_METHOD'] ?? 'GET'));
if (str_starts_with($path, '/dev/')) {
    $remote = (string) ($_SERVER['REMOTE_ADDR'] ?? '');
    if (getenv('APP_ENV') !== 'development' || !in_array($remote, ['127.0.0.1', '::1'], true) || !Auth::is('admin')) {
        http_response_code(404);
        echo 'Page introuvable.';
        exit();
    }
}
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
    if (!Auth::validCsrf($_POST['csrf'] ?? null)) {
        http_response_code(419);
        echo 'Session expirée. Rechargez la page puis réessayez.';
        exit();
    }
    if (!Auth::canWrite($path)) {
        http_response_code(403);
        echo 'Votre rôle ne permet pas cette action.';
        exit();
    }
    if (!in_array($path, ['/settings/users/save', '/settings/backups/restore'], true)) {
        $entityId = (int) ($_POST['animal_id'] ?? ($_POST['id'] ?? 0)) ?: null;
        $fields = implode(',', array_keys($_POST));
        register_shutdown_function(static function () use ($path, $entityId, $fields): void {
            $error = error_get_last();
            if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR], true)) {
                return;
            }
            $code = http_response_code();
            if ($code === false || $code < 400) {
                AuditService::log('post', $path, 'Action effectuée', $entityId ? 'animal' : null, $entityId, [
                    'fields' => $fields,
                ]);
            }
        });
    }
}

require __DIR__ . '/../app/Routes/web.php';
