# ============================================================
# 预览环境 Nginx 配置模板
# 支持 *.preview.xiaoxiajianji.com 通配符子域名
#
# 使用方法：
# 1. 将本文件复制到 Nginx 配置目录（如 /etc/nginx/conf.d/preview.conf）
# 2. 根据实际情况修改域名和 API 地址
# 3. 运行 nginx -t 测试配置
# 4. 运行 nginx -s reload 重载配置
#
# 前置条件：
# - DNS 已配置 *.preview.xiaoxiajianji.com 指向本服务器
# - 预览根目录已创建：/var/www/preview/
# - 每个 PR 的静态文件放在 /var/www/preview/pr-{N}/ 下
# ============================================================

# ---- 变量定义 ----
# 从子域名中提取 PR 号（如 pr-123.preview -> pr-123）
map $host $preview_pr {
    default "";
    ~^(?<pr>pr-\d+)\.preview\.xiaoxiajianji\.com$ $pr;
}

# ---- HTTP 服务器（80端口） ----
server {
    listen 80;
    server_name *.preview.xiaoxiajianji.com;

    # 根目录根据子域名动态映射
    root /var/www/preview/$preview_pr;

    # 索引文件
    index index.html;

    # 字符集
    charset utf-8;

    # 访问日志
    access_log /var/log/nginx/preview_access.log;
    error_log /var/log/nginx/preview_error.log warn;

    # 如果子域名格式不正确，返回404
    if ($preview_pr = "") {
        return 404;
    }

    # 如果预览目录不存在，返回404
    if (!-d $document_root) {
        return 404;
    }

    # ---- API 反向代理到 staging 环境 ----
    location /api/ {
        proxy_pass https://staging-api.xiaoxiajianji.com/api/;
        proxy_http_version 1.1;

        # 请求头设置
        proxy_set_header Host staging-api.xiaoxiajianji.com;
        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 X-Forwarded-Host $host;

        # 超时设置
        proxy_connect_timeout 30s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;

        # 缓冲设置
        proxy_buffering on;
        proxy_buffer_size 4k;
        proxy_buffers 8 4k;

        # 重定向跟随
        proxy_redirect off;

        # WebSocket 支持（如需要，取消注释）
        # proxy_set_header Upgrade $http_upgrade;
        # proxy_set_header Connection "upgrade";
    }

    # ---- 生成文件代理（如需要） ----
    # location /generated-files/ {
    #     proxy_pass https://staging-api.xiaoxiajianji.com/generated-files/;
    #     proxy_http_version 1.1;
    #     proxy_set_header Host staging-api.xiaoxiajianji.com;
    #     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 /assets/ {
        expires 7d;
        add_header Cache-Control "public, max-age=604800, immutable";
        try_files $uri =404;
    }

    # ---- SPA 路由支持 ----
    location / {
        try_files $uri $uri/ /index.html;
    }

    # ---- 安全相关响应头 ----
    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 ~ /\. {
        deny all;
        access_log off;
        log_not_found off;
    }

    # ---- 禁止敏感文件访问 ----
    location ~* \.(env|log|sql|bak|swp|tmp|zip|tar|gz)$ {
        deny all;
        access_log off;
        log_not_found off;
    }
}

# ============================================================
# HTTPS 服务器配置（可选，需要 SSL 证书）
#
# 推荐使用 Let's Encrypt 通配符证书：
#   certbot certonly --dns-xxx -d "*.preview.xiaoxiajianji.com"
#
# 启用方法：取消下方注释，并修改证书路径
# ============================================================
#
# server {
#     listen 443 ssl http2;
#     server_name *.preview.xiaoxiajianji.com;
#
#     # SSL 证书配置
#     ssl_certificate /etc/letsencrypt/live/preview.xiaoxiajianji.com/fullchain.pem;
#     ssl_certificate_key /etc/letsencrypt/live/preview.xiaoxiajianji.com/privkey.pem;
#
#     # SSL 安全配置
#     ssl_protocols TLSv1.2 TLSv1.3;
#     ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
#     ssl_prefer_server_ciphers off;
#     ssl_session_cache shared:SSL:10m;
#     ssl_session_timeout 10m;
#     ssl_session_tickets off;
#
#     # OCSP Stapling
#     ssl_stapling on;
#     ssl_stapling_verify on;
#
#     # 根目录根据子域名动态映射
#     root /var/www/preview/$preview_pr;
#
#     # 索引文件
#     index index.html;
#
#     # 字符集
#     charset utf-8;
#
#     # 访问日志
#     access_log /var/log/nginx/preview_ssl_access.log;
#     error_log /var/log/nginx/preview_ssl_error.log warn;
#
#     # 如果子域名格式不正确，返回404
#     if ($preview_pr = "") {
#         return 404;
#     }
#
#     # 如果预览目录不存在，返回404
#     if (!-d $document_root) {
#         return 404;
#     }
#
#     # API 反向代理到 staging 环境
#     location /api/ {
#         proxy_pass https://staging-api.xiaoxiajianji.com/api/;
#         proxy_http_version 1.1;
#         proxy_set_header Host staging-api.xiaoxiajianji.com;
#         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 X-Forwarded-Host $host;
#         proxy_connect_timeout 30s;
#         proxy_send_timeout 60s;
#         proxy_read_timeout 60s;
#         proxy_buffering on;
#         proxy_buffer_size 4k;
#         proxy_buffers 8 4k;
#     }
#
#     # 静态资源缓存
#     location /assets/ {
#         expires 7d;
#         add_header Cache-Control "public, max-age=604800, immutable";
#         try_files $uri =404;
#     }
#
#     # SPA 路由支持
#     location / {
#         try_files $uri $uri/ /index.html;
#     }
#
#     # 安全相关响应头
#     add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" 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 ~ /\. {
#         deny all;
#         access_log off;
#         log_not_found off;
#     }
#
#     # 禁止敏感文件访问
#     location ~* \.(env|log|sql|bak|swp|tmp|zip|tar|gz)$ {
#         deny all;
#         access_log off;
#         log_not_found off;
#     }
# }
