<?php

namespace App\Http\Middleware;

use App\Providers\AppServiceProvider;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

/**
 * 强制 WWW 跳转中间件
 *
 * 开启后（config_items.code = force_www_redirect = '1'）：
 * - 已绑定应用的子域名（如 a.xx.com）：正常访问
 * - www 子域名（如 www.xx.com）：正常访问
 * - 根域名（如 xx.com）：301 跳转到 www.xx.com
 * - 未绑定的子域名（如 b.xx.com）：301 跳转到 www.xx.com
 *
 * 主域名来源：.env 的 APP_URL（与 main_url() 辅助函数保持一致）。
 * 主域名已以 www. 开头时直接作为目标；否则加 www. 前缀。
 */
class ForceWwwRedirect
{
    public function handle(Request $request, Closure $next)
    {
        // 配置开关关闭时直接放行
        if (!$this->isEnabled()) {
            return $next($request);
        }

        $host = $request->getHost();

        // 开发环境或 IP/localhost 放行
        if ($this->shouldSkip($host)) {
            return $next($request);
        }

        // 已是 www. 开头，放行
        if (str_starts_with($host, 'www.')) {
            return $next($request);
        }

        // 已绑定应用的子域名，放行
        if (in_array($host, AppServiceProvider::getBoundDomains(), true)) {
            return $next($request);
        }

        // 从 APP_URL 提取主域名
        $mainHost = parse_url(config('app.url'), PHP_URL_HOST);
        if (!$mainHost) {
            return $next($request);
        }

        // 目标 host：APP_URL 已 www. 开头则直接用，否则加 www. 前缀
        $targetHost = str_starts_with($mainHost, 'www.') ? $mainHost : 'www.' . $mainHost;

        // 防御性：当前 host 已等于目标 host，放行
        if ($host === $targetHost) {
            return $next($request);
        }

        // 构造目标 URL，保留 scheme、path、query
        $targetUrl = $request->getScheme() . '://' . $targetHost . $request->getRequestUri();

        // 使用 301 永久重定向（利于 SEO），但添加 Cache-Control: no-store 防止浏览器永久缓存
        // 因为配置（force_www_redirect 开关、应用 access_mode）可能随时变更，
        // 若浏览器缓存 301，配置变更后用户无法访问新地址（Ctrl+F5 也无法清除 301 缓存）
        return redirect()->away($targetUrl, 301)
            ->header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0');
    }

    /**
     * 读取配置开关
     *
     * 直接查表避免依赖模型缓存（与 AppServiceProvider::applySessionLifetime 同样的模式）
     */
    protected function isEnabled(): bool
    {
        try {
            return DB::table('config_items')
                ->where('code', 'force_www_redirect')
                ->where('status', 1)
                ->value('value') === '1';
        } catch (\Throwable) {
            return false;
        }
    }

    /**
     * 判断是否跳过重定向（开发环境兼容）
     */
    protected function shouldSkip(string $host): bool
    {
        // IP 地址（IPv4/IPv6）
        if (filter_var($host, FILTER_VALIDATE_IP)) {
            return true;
        }

        // localhost 及回环地址
        if (in_array($host, ['localhost', '127.0.0.1', '::1'], true)) {
            return true;
        }

        // 单段主机名（无点号，如 localhost、内部主机名）
        if (!str_contains($host, '.')) {
            return true;
        }

        return false;
    }
}
