<?php

declare(strict_types=1);

namespace app\common\middleware;

use Webman\MiddlewareInterface;
use Webman\Http\Request;
use Webman\Http\Response;

/**
 * 跨域请求支持（Webman 迁移版）
 * 安全起见，只支持配置中的域名
 */
class AllowCrossDomain implements MiddlewareInterface
{
    protected array $header = [
        'Access-Control-Allow-Credentials' => 'true',
        'Access-Control-Max-Age'           => '1800',
        'Access-Control-Allow-Methods'     => '*',
        'Access-Control-Allow-Headers'     => '*',
    ];

    /**
     * 返回 CORS 预检（OPTIONS）响应，供路由直接调用（Webman 未匹配路由时不走中间件）
     */
    public static function optionsResponse(Request $request): Response
    {
        $header = [
            'Access-Control-Allow-Credentials' => 'true',
            'Access-Control-Max-Age'            => '1800',
            'Access-Control-Allow-Methods'      => 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
            'Access-Control-Allow-Headers'      => 'Content-Type, Authorization, batoken, ba-user-token, user-token, access-token, think-lang, server',
        ];
        $origin = $request->header('origin');
        if (is_array($origin)) {
            $origin = $origin[0] ?? '';
        }
        $origin = is_string($origin) ? trim($origin) : '';
        if ($origin !== '') {
            $info = parse_url($origin);
            $host = $info['host'] ?? '';
            $corsDomain = array_map('trim', explode(',', config('buildadmin.cors_request_domain', '')));
            $corsDomain[] = $request->host(true);
            $allowed = in_array('*', $corsDomain)
                || in_array($origin, $corsDomain)
                || in_array($host, $corsDomain)
                || ($host === 'localhost' || $host === '127.0.0.1');
            if ($allowed) {
                $header['Access-Control-Allow-Origin'] = $origin;
            }
        }
        return response('', 204, $header);
    }

    public function process(Request $request, callable $handler): Response
    {
        $path = trim($request->path(), '/');
        if (!str_starts_with($path, 'api/') && !str_starts_with($path, 'admin/')) {
            return $handler($request);
        }

        $header = $this->header;

        $origin = $request->header('origin');
        if (is_array($origin)) {
            $origin = $origin[0] ?? '';
        }
        $origin = is_string($origin) ? trim($origin) : '';

        if ($origin !== '') {
            $info = parse_url($origin);
            $host = $info['host'] ?? '';
            $corsDomain = array_map('trim', explode(',', config('buildadmin.cors_request_domain', '')));
            $corsDomain[] = $request->host(true);

            $allowed = in_array('*', $corsDomain)
                || in_array($origin, $corsDomain)
                || in_array($host, $corsDomain)
                || ($host === 'localhost' || $host === '127.0.0.1');

            if ($allowed) {
                $header['Access-Control-Allow-Origin'] = $origin;
            }
        }

        if ($request->method() === 'OPTIONS') {
            return response('', 204, $header);
        }

        $response = $handler($request);
        return $response->withHeaders($header);
    }
}
