# Edge reverse proxy — single entry point (replaces Caddy).
# Optional upstreams use Docker DNS resolver so nginx starts even if a module is disabled.

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

# Reflect browser Origin for cross-origin API calls (web app on :3000, API on :80).
map $http_origin $cors_allow_origin {
    default $http_origin;
    ''      '*';
}

server {
    listen 80;
    server_name ${DOMAIN};

    client_max_body_size 10G;

    # ultid API (must stay after ^~ /api/auth/ — mail OIDC routes)
    location /api/ {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $ultid_upstream ultid:8080;

        proxy_hide_header Access-Control-Allow-Origin;
        proxy_hide_header Access-Control-Allow-Methods;
        proxy_hide_header Access-Control-Allow-Headers;
        proxy_hide_header Access-Control-Expose-Headers;
        proxy_hide_header Access-Control-Max-Age;
        proxy_hide_header Access-Control-Allow-Credentials;
        proxy_hide_header Vary;

        add_header Access-Control-Allow-Origin $cors_allow_origin always;
        add_header Access-Control-Allow-Methods "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS" always;
        add_header Access-Control-Allow-Headers "Accept, Authorization, Content-Type, Idempotency-Key, Origin, X-Requested-With, X-Trace-Id" always;
        add_header Access-Control-Expose-Headers "X-Trace-Id" always;
        add_header Access-Control-Max-Age 300 always;
        add_header Vary Origin always;

        proxy_pass http://$ultid_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /ws {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $ultid_ws_upstream ultid:8080;

        proxy_hide_header Access-Control-Allow-Origin;

        add_header Access-Control-Allow-Origin $cors_allow_origin always;
        add_header Vary Origin always;

        proxy_pass http://$ultid_ws_upstream;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # TipTap / Hocuspocus — proxy WS without redirect (301 breaks upgrade)
    location /collab {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $hocuspocus_upstream host.docker.internal:1234;

        rewrite ^/collab/?(.*)$ /$1 break;
        proxy_pass http://$hocuspocus_upstream;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
    }

    # Ultimail OIDC post-login — before Authentik /auth/ (path collision)
    location ^~ /auth/complete {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
        proxy_pass http://$mail_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    location /auth/ {
        proxy_pass http://authentik-server:9000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_read_timeout 86400;
    }

    location /meet/ {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $jitsi_upstream jitsi-web;
        rewrite ^/meet/(.*)$ /$1 break;
        proxy_pass http://$jitsi_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # Public Nextcloud share links → UltiDrive viewer
    location ~ ^/cloud/index\.php/s/([^/]+)/?(.*)$ {
        return 301 /drive/s/$1$is_args$args;
    }

    location /cloud/ {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $nc_upstream nextcloud;
        rewrite ^/cloud/(.*)$ /$1 break;
        proxy_pass http://$nc_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location = /cloud {
        return 301 /cloud/;
    }

    # OnlyOffice fetches Nextcloud after StorageUrl host rewrite (URLs lack /cloud prefix).
    location ^~ /index.php {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $nc_upstream nextcloud;
        proxy_pass http://$nc_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 300s;
    }

    location /office/ {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $oo_upstream onlyoffice;
        rewrite ^/office/(.*)$ /$1 break;
        proxy_pass http://$oo_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host/office;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_read_timeout 3600s;
    }

    location = /office {
        return 301 /office/;
    }

    # UltiDrive — same suite frontend as mail (unified Next.js app)
    location /drive/ {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
        proxy_pass http://$mail_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    location = /drive {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
        proxy_pass http://$mail_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    # Ulti Suite frontend (mail + drive + contacts) — dev: pnpm dev on host (MAIL_FRONTEND_UPSTREAM=host.docker.internal:3000)
    # Prod: set MAIL_FRONTEND_UPSTREAM=suite-frontend:3000
    location ^~ /api/auth/ {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
        proxy_pass http://$mail_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location ^~ /mail/ {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
        proxy_pass http://$mail_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    # Do not 301 /mail → /mail/ (Next 308 /mail/ → /mail causes a redirect loop).
    location = /mail {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
        proxy_pass http://$mail_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    location = /mail/ {
        return 302 /mail/inbox;
    }

    location ^~ /login {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
        proxy_pass http://$mail_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    location ^~ /contacts {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
        proxy_pass http://$mail_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    # Console d'administration suite
    location ^~ /admin {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
        proxy_pass http://$mail_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    location ^~ /_next/ {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
        proxy_pass http://$mail_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    location ^~ /brand/ {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
        proxy_pass http://$mail_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location ^~ /mail-backgrounds/ {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
        proxy_pass http://$mail_upstream;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # Public assets at repo root (launcher icons, etc.)
    location ~* ^/[^/]+\.(svg|png|ico|webp)$ {
        resolver 127.0.0.11 valid=10s ipv6=off;
        set $mail_upstream ${MAIL_FRONTEND_UPSTREAM};
        proxy_pass http://$mail_upstream$request_uri;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location = / {
        return 302 /mail/inbox;
    }

    location / {
        default_type text/plain;
        return 404 "Not found\n";
    }
}
