# =============================================================================
# Configuration NGINX PRODUCTION pour pra-geo (IN4)
# Date: 2025-10-07
# Environnement: PRODUCTION
# Server: IN4 (51.159.7.190)
# =============================================================================

# Site principal (redirection vers www ou app)
server {
    listen 80;
    server_name geosector.fr;

    # Redirection permanente vers HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name geosector.fr;

    # Certificats SSL
    ssl_certificate /etc/letsencrypt/live/geosector.fr/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/geosector.fr/privkey.pem;

    # Configuration SSL optimisée
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_stapling on;
    ssl_stapling_verify on;

    root /var/www/geosector/web;
    index index.html;

    # Logs PRODUCTION
    access_log /var/log/nginx/geosector-web_access.log combined;
    error_log /var/log/nginx/geosector-web_error.log warn;

    # Headers de sécurité
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    location / {
        try_files $uri $uri/ /index.html;
    }

    # Assets statiques avec cache agressif
    location ~* \.(jpg|jpeg|png|gif|ico|svg|webp|css|js|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # Protection des fichiers sensibles
    location ~ /\.(?!well-known) {
        deny all;
        access_log off;
        log_not_found off;
    }
}

# =============================================================================
# APPLICATION FLUTTER + API PHP
# =============================================================================

# Redirection HTTP → HTTPS
server {
    listen 80;
    server_name app3.geosector.fr;

    # Permettre Let's Encrypt validation
    location ^~ /.well-known/acme-challenge/ {
        root /var/www/letsencrypt;
        allow all;
    }

    # Redirection permanente vers HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name app3.geosector.fr;

    # Certificats SSL
    ssl_certificate /etc/letsencrypt/live/app3.geosector.fr/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app3.geosector.fr/privkey.pem;

    # Configuration SSL optimisée (même que ci-dessus)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_stapling on;
    ssl_stapling_verify on;

    # Logs PRODUCTION
    access_log /var/log/nginx/pra-app_access.log combined;
    error_log /var/log/nginx/pra-app_error.log warn;

    # Headers de sécurité globaux
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    # Taille maximale des uploads (pour les logos, exports, etc.)
    client_max_body_size 10M;
    client_body_buffer_size 128k;

    # Timeouts optimisés pour PRODUCTION
    client_body_timeout 30s;
    client_header_timeout 30s;
    send_timeout 60s;

    # =============================================================================
    # APPLICATION FLUTTER (contenu statique)
    # =============================================================================
    location / {
        root /var/www/geosector/app;
        index index.html;
        try_files $uri $uri/ /index.html;

        # Cache intelligent pour PRODUCTION
        # HTML : pas de cache (pour déploiements)
        location ~* \.html$ {
            expires -1;
            add_header Cache-Control "no-cache, no-store, must-revalidate";
        }

        # Assets Flutter (JS, CSS, fonts) avec hash : cache agressif
        location ~* \.(js|css|woff|woff2|ttf|eot)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
            access_log off;
        }

        # Images : cache longue durée
        location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
            expires 30d;
            add_header Cache-Control "public";
            access_log off;
        }
    }

    # =============================================================================
    # API PHP (RESTful)
    # =============================================================================
    location /api/ {
        root /var/www/geosector;

        # CORS - Liste blanche des origines autorisées en PRODUCTION
        set $cors_origin "";

        # Autoriser uniquement les domaines de production
        if ($http_origin ~* ^https://(app\.geosector\.fr|geosector\.fr)$) {
            set $cors_origin $http_origin;
        }

        # Gestion des preflight requests (OPTIONS)
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' $cors_origin always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always;
            add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;
            add_header 'Access-Control-Max-Age' 86400;
            add_header 'Content-Type' 'text/plain; charset=utf-8';
            add_header 'Content-Length' 0;
            return 204;
        }

        # Headers CORS pour les requêtes normales
        add_header 'Access-Control-Allow-Origin' $cors_origin always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;

        # Cache API : pas de cache (données dynamiques)
        add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate" always;
        add_header Pragma "no-cache" always;
        add_header Expires "0" always;

        # Headers de sécurité spécifiques API
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-Frame-Options "DENY" always;

        # Rewrite vers index.php
        try_files $uri $uri/ /api/index.php$is_args$args;

        # Traitement PHP
        location ~ ^/api/(.+\.php)$ {
            root /var/www/geosector;

            # FastCGI PHP-FPM
            fastcgi_pass unix:/run/php-fpm83/php-fpm.sock;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $request_filename;

            # Variable d'environnement PRODUCTION
            fastcgi_param APP_ENV "production";
            fastcgi_param SERVER_NAME "app3.geosector.fr";

            # Headers transmis à PHP
            fastcgi_param HTTP_X_REAL_IP $remote_addr;
            fastcgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
            fastcgi_param HTTP_X_FORWARDED_PROTO $scheme;

            # Timeouts pour opérations longues (sync, exports)
            fastcgi_read_timeout 300;
            fastcgi_send_timeout 300;
            fastcgi_connect_timeout 60;

            # Buffers optimisés
            fastcgi_buffer_size 128k;
            fastcgi_buffers 256 16k;
            fastcgi_busy_buffers_size 256k;
            fastcgi_temp_file_write_size 256k;

            # Headers CORS pour réponses PHP
            add_header 'Access-Control-Allow-Origin' $cors_origin always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;
        }
    }

    # =============================================================================
    # UPLOADS ET MÉDIAS
    # =============================================================================
    location /api/uploads/ {
        alias /var/www/geosector/api/uploads/;

        # Cache pour les médias uploadés
        expires 7d;
        add_header Cache-Control "public";

        # Sécurité : empêcher l'exécution de scripts
        location ~ \.(php|phtml|php3|php4|php5|phps)$ {
            deny all;
        }
    }

    # =============================================================================
    # SÉCURITÉ
    # =============================================================================

    # Bloquer l'accès aux fichiers sensibles
    location ~ /\.(?!well-known) {
        deny all;
        access_log off;
        log_not_found off;
    }

    # Bloquer l'accès aux fichiers de configuration
    location ~* \.(env|sql|bak|backup|swp|config|conf|ini|log)$ {
        deny all;
        access_log off;
        log_not_found off;
    }

    # Bloquer les user-agents malveillants
    if ($http_user_agent ~* (bot|crawler|spider|scraper|wget|curl)) {
        return 403;
    }

    # Protection contre les requêtes invalides
    if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE|PATCH|OPTIONS)$) {
        return 405;
    }

    # =============================================================================
    # MONITORING
    # =============================================================================

    # Endpoint de health check (accessible uniquement en local)
    location = /nginx-health {
        access_log off;
        allow 127.0.0.1;
        allow 13.23.34.0/24;  # Réseau interne Incus
        deny all;
        return 200 "healthy\n";
        add_header Content-Type text/plain;
    }
}
