###############################################################################
#  default.conf · 业务入口（SPA + API + WebSocket）
###############################################################################

# ============================================================
# HTTP → HTTPS 301 跳转
# ============================================================
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    # 留给 Let's Encrypt 验证
    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

# ============================================================
# HTTPS 主站
# ============================================================
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;

    # ---- 证书 ----
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # ---- TLS 配置（A+） ----
    ssl_protocols           TLSv1.2 TLSv1.3;
    ssl_ciphers             ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;
    ssl_session_cache    shared:SSL:10m;
    ssl_session_timeout  1d;
    ssl_session_tickets  off;
    ssl_stapling          on;
    ssl_stapling_verify   on;
    resolver 1.1.1.1 8.8.8.8 valid=300s;

    # ---- 安全响应头 ----
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Frame-Options          SAMEORIGIN always;
    add_header X-Content-Type-Options   nosniff   always;
    add_header Referrer-Policy          "strict-origin-when-cross-origin" always;

    # ---- 站点根目录（前端打包产物） ----
    root  /var/www/html;
    index index.html;

    # ============================================================
    # 1. 健康检查（Nginx 自身）
    # ============================================================
    location = /healthz {
        access_log off;
        return 200 "ok\n";
        add_header Content-Type text/plain;
    }

    # ============================================================
    # 2. API 反向代理 + 限流 + 短缓存
    # ============================================================
    location /api/ {
        # 限流：每 IP 20 r/s，突发 40
        limit_req zone=api_limit burst=40 nodelay;

        proxy_pass http://api_backend/;
        proxy_http_version 1.1;
        proxy_set_header Connection         "";
        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_connect_timeout 5s;
        proxy_send_timeout    30s;
        proxy_read_timeout    30s;

        proxy_next_upstream error timeout http_502 http_503 http_504;
        proxy_next_upstream_tries   2;
        proxy_next_upstream_timeout 10s;

        # 仅 GET /api/products 这类接口可短缓存（按需开启）
        # proxy_cache         api_cache;
        # proxy_cache_valid   200 5m;
        # proxy_cache_key     "$scheme$request_method$host$request_uri";
        # proxy_cache_bypass  $http_authorization $cookie_nocache;
        # proxy_no_cache      $http_authorization $cookie_nocache;
        # add_header X-Cache-Status $upstream_cache_status always;
    }

    # ============================================================
    # 3. WebSocket
    # ============================================================
    location /ws/ {
        proxy_pass http://ws_backend/;

        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_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }

    # ============================================================
    # 4. 静态资源（带 hash → 强缓存 1 年）
    # ============================================================
    location /assets/ {
        expires 1y;
        add_header Cache-Control "public, immutable" always;
        access_log off;
    }

    location ~* \.[a-f0-9]{8,}\.(?:js|css|png|jpg|webp|svg|woff2?)$ {
        expires 1y;
        add_header Cache-Control "public, immutable" always;
        access_log off;
    }

    # ============================================================
    # 5. SPA history 模式 fallback
    # ============================================================
    location = /index.html {
        expires -1;
        add_header Cache-Control "no-cache, must-revalidate" always;
    }

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

    # ============================================================
    # 6. 隐藏文件 / 错误页
    # ============================================================
    location ~ /\. {
        deny all;
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }
}
