<?php

namespace XZD\AI\V5\Tools;

use XZD\AI\V5\Core\Logger;
use XZD\AI\V5\Core\Config;

// WordPress 未内置 link_meta 系列函数，提供兼容层
if (!function_exists('XZD\AI\V5\Tools\register_link_meta_support')) {
    function register_link_meta_support(): void {
        global $wpdb;
        $table = $wpdb->prefix . 'linkmeta';
        if ($wpdb->get_var("SHOW TABLES LIKE '{$table}'") !== $table) {
            $charset = $wpdb->get_charset_collate();
            $wpdb->query("CREATE TABLE {$table} (
                meta_id bigint(20) unsigned NOT NULL auto_increment,
                link_id bigint(20) unsigned NOT NULL default '0',
                meta_key varchar(255) default NULL,
                meta_value longtext,
                PRIMARY KEY (meta_id),
                KEY link_id (link_id),
                KEY meta_key (meta_key(191))
            ) {$charset}");
        }
    }
}
if (!function_exists('XZD\AI\V5\Tools\get_link_meta')) {
    function get_link_meta(int $linkId, string $key = '', bool $single = true) {
        register_link_meta_support();
        return get_metadata('link', $linkId, $key, $single);
    }
}
if (!function_exists('XZD\AI\V5\Tools\update_link_meta')) {
    function update_link_meta(int $linkId, string $key, $value): bool {
        register_link_meta_support();
        return update_metadata('link', $linkId, $key, $value) !== false;
    }
}

/**
 * 友链管理系统 - 添加、删除、审核、验证、白名单、定时监控
 *
 * 白名单机制：白名单内的友链跳过自动检测，只标记不删除。
 * 防误判：body<500字符/非200响应/SPA 判为 uncertain。
 * 连续3次丢失才发通知。
 */
class FriendLinkManager
{
    private const STATUS_META    = '_xzd_link_status';
    private const LOST_AT_META  = '_xzd_link_lost_at';
    private const FAIL_COUNT    = '_xzd_link_fail_count';
    private const WHITELIST     = '_xzd_link_whitelist';
    private const LOST_ALERT_THRESHOLD = 3; // 连续失败N次后发通知

    private static function ensureBookmarkFunctions(): void
    {
        if (!function_exists('wp_update_link')) {
            require_once ABSPATH . 'wp-admin/includes/bookmark.php';
        }
    }

    // 工具入口

    /** 列出所有友链，含互链状态、白名单标记，支持 check_all 批量检测 */
    public static function listFriendLinks(array $params, int $userId): ToolResult
    {
        self::ensureBookmarkFunctions();
        $links = get_bookmarks(['hide_invisible' => false]);

        // check_all 参数触发批量检测
        if (!empty($params['check_all'])) {
            $batchLimit = (int)($params['batch_limit'] ?? 20);
            return self::checkAllFriendLinks(['batch_limit' => $batchLimit], $userId);
        }

        if (empty($links)) {
            return ToolResult::success(['links' => [], 'total' => 0], '暂无友链');
        }

        $list = [];
        foreach ($links as $link) {
            $catNames = [];
            $cats = wp_get_object_terms($link->link_id, 'link_category');
            if (!is_wp_error($cats) && !empty($cats)) {
                $catNames = array_map(fn($c) => $c->name, $cats);
            }

            $status    = get_link_meta($link->link_id, self::STATUS_META, true) ?: 'unknown';
            $lostAt    = get_link_meta($link->link_id, self::LOST_AT_META, true);
            $failCount = (int)get_link_meta($link->link_id, self::FAIL_COUNT, true);
            $whitelist = (bool)get_link_meta($link->link_id, self::WHITELIST, true);

            $list[] = [
                'link_id'          => (int)$link->link_id,
                'link_name'        => $link->link_name,
                'link_url'         => $link->link_url,
                'link_description' => $link->link_description ?? '',
                'link_image'       => $link->link_image ?? '',
                'link_visible'     => $link->link_visible,
                'link_owner'       => (int)$link->link_owner,
                'categories'       => $catNames,
                'status'           => $status,
                'lost_at'          => $lostAt,
                'fail_count'       => $failCount,
                'is_whitelist'     => $whitelist,
            ];
        }

        $allCats = get_terms(['taxonomy' => 'link_category', 'hide_empty' => false]);
        $catsInfo = [];
        if (!is_wp_error($allCats)) {
            foreach ($allCats as $cat) {
                $catsInfo[] = ['id' => $cat->term_id, 'name' => $cat->name, 'slug' => $cat->slug];
            }
        }

        return ToolResult::success([
            'links'      => $list,
            'total'      => count($list),
            'categories' => $catsInfo,
        ], '共 ' . count($list) . ' 条友链');
    }

    /** 添加友链 */
    public static function addFriendLink(array $params, int $userId): ToolResult
    {
        self::ensureBookmarkFunctions();
        $url = rtrim($params['url'] ?? '', '/');
        if (!$url || !filter_var($url, FILTER_VALIDATE_URL)) {
            return ToolResult::error('请提供有效的网站URL');
        }

        $existing = get_bookmarks(['search' => $url]);
        if (!empty($existing)) {
            foreach ($existing as $ex) {
                if (rtrim($ex->link_url, '/') === $url) {
                    return ToolResult::error("友链已存在（ID: {$ex->link_id}，名称: {$ex->link_name}）");
                }
            }
        }

        $name = $params['name'] ?? '';
        $category = $params['category'] ?? '';
        $description = $params['description'] ?? '';

        $siteInfo = $name && $description ? null : self::fetchSiteInfo($url);
        if (!$name) $name = $siteInfo['title'] ?? parse_url($url, PHP_URL_HOST) ?: $url;
        if (!$description) $description = $siteInfo['description'] ?? $name;

        $catId = null;
        if ($category) {
            $term = term_exists($category, 'link_category');
            if ($term) {
                $catId = is_array($term) ? (int)$term['term_id'] : (int)$term;
            } else {
                $newTerm = wp_insert_term($category, 'link_category');
                if (!is_wp_error($newTerm)) $catId = (int)$newTerm['term_id'];
            }
        }
        if (!$catId && $siteInfo && !empty($siteInfo['suggested_category'])) {
            $term = term_exists($siteInfo['suggested_category'], 'link_category');
            if ($term) {
                $catId = is_array($term) ? (int)$term['term_id'] : (int)$term;
            } else {
                $newTerm = wp_insert_term($siteInfo['suggested_category'], 'link_category');
                if (!is_wp_error($newTerm)) $catId = (int)$newTerm['term_id'];
            }
        }

        $reciprocal = self::checkReciprocal($url);
        $isMutual = $reciprocal['status'] === 'found';
        $linkVisible = $isMutual ? 'Y' : 'N';

        $image = $params['image'] ?? '';
        if (!$image && $siteInfo && !empty($siteInfo['favicon'])) $image = $siteInfo['favicon'];

        if (!function_exists('wp_insert_link')) {
            require_once ABSPATH . 'wp-admin/includes/bookmark.php';
        }

        $linkData = [
            'link_name'        => $name,
            'link_url'         => $url,
            'link_description' => $description,
            'link_image'       => $image,
            'link_visible'     => $linkVisible,
            'link_target'      => '_blank',
            'link_owner'       => $userId,
            'link_updated'     => current_time('mysql'),
        ];
        if ($catId) $linkData['link_category'] = [$catId];

        $linkId = wp_insert_link($linkData, true);
        if (is_wp_error($linkId)) {
            return ToolResult::error('添加友链失败: ' . $linkId->get_error_message());
        }

        update_link_meta($linkId, self::STATUS_META, $reciprocal['status']);
        update_link_meta($linkId, self::FAIL_COUNT, 0);
        update_link_meta($linkId, self::WHITELIST, false);

        $catName = $catId ? (get_term($catId)->name ?? '未分类') : '未分类';
        $statusMsg = $isMutual
            ? "{$name} 已添加并通过（检测到互链）"
            : "{$name} 已添加为待审（未检测到互链）";

        Logger::info('friend_link', "添加友链 #{$linkId} «{$name}» {$url} 互链:{$isMutual}");
        return ToolResult::success([
            'link_id'      => $linkId,
            'link_name'    => $name,
            'link_url'     => $url,
            'link_visible' => $linkVisible,
            'is_mutual'    => $isMutual,
            'category'     => $catName,
        ], $statusMsg);
    }

    /** 删除友链 - 仅管理员手动调用 */
    public static function deleteFriendLink(array $params, int $userId): ToolResult
    {
        self::ensureBookmarkFunctions();
        $linkId = (int)($params['link_id'] ?? 0);
        $linkUrl = $params['link_url'] ?? '';

        if (!$linkId && !$linkUrl) return ToolResult::error('请提供友链ID或URL');
        if ($linkUrl && !$linkId) {
            $links = get_bookmarks(['search' => $linkUrl]);
            if (empty($links)) return ToolResult::error("未找到URL为 {$linkUrl} 的友链");
            $linkId = (int)$links[0]->link_id;
        }

        $link = get_bookmark($linkId);
        if (!$link) return ToolResult::error('友链不存在');

        if (!function_exists('wp_delete_link')) {
            require_once ABSPATH . 'wp-admin/includes/bookmark.php';
        }
        $result = wp_delete_link($linkId);
        if (!$result) return ToolResult::error("删除友链 #{$linkId} 失败");

        Logger::info('friend_link', "删除友链 #{$linkId} «{$link->link_name}» {$link->link_url}");
        return ToolResult::success(['link_id' => $linkId, 'link_name' => $link->link_name, 'link_url' => $link->link_url], "友链«{$link->link_name}»已删除");
    }

    /** 审核友链 - 合并 approve + reject */
    public static function reviewFriendLink(array $params, int $userId): ToolResult
    {
        self::ensureBookmarkFunctions();
        $linkId = (int)($params['link_id'] ?? 0);
        $action = $params['action'] ?? 'approve';

        if (!$linkId) return ToolResult::error('请提供友链ID');
        if (!in_array($action, ['approve', 'reject'], true)) return ToolResult::error('action 必须是 approve 或 reject');

        $link = get_bookmark($linkId);
        if (!$link) return ToolResult::error('友链不存在');

        if ($action === 'approve') {
            $notes = $params['notes'] ?? '';
            $siteInfo = self::fetchSiteInfo($link->link_url);
            $catId = null;
            if ($siteInfo && !empty($siteInfo['suggested_category'])) {
                $term = term_exists($siteInfo['suggested_category'], 'link_category');
                if ($term) {
                    $catId = is_array($term) ? (int)$term['term_id'] : (int)$term;
                } else {
                    $newTerm = wp_insert_term($siteInfo['suggested_category'], 'link_category');
                    if (!is_wp_error($newTerm)) $catId = (int)$newTerm['term_id'];
                }
            }

            $updateData = [
                'link_id'      => $linkId,
                'link_visible' => 'Y',
                'link_target'  => '_blank',
                'link_notes'   => $notes,
                'link_updated' => current_time('mysql'),
            ];
            if ($catId) $updateData['link_category'] = [$catId];
            wp_update_link($updateData);

            $catName = $catId ? (get_term($catId)->name ?? '未分类') : '未分类';
            if ($link->link_owner) {
                $adapter = \XZD\AI\V5\Theme\AdapterRegistry::getCurrent();
                $adapter->sendNotification((int)$link->link_owner, '友链申请已通过', "您的友链«{$link->link_name}»已通过审核。", 1);
            }
            Logger::info('friend_link', "通过友链 #{$linkId} «{$link->link_name}» 分类:{$catName}");
            return ToolResult::success(['link_id' => $linkId, 'link_name' => $link->link_name, 'category' => $catName], "友链«{$link->link_name}»已通过");
        }

        // reject
        $reason = $params['reason'] ?? '管理员拒绝';
        wp_update_link(['link_id' => $linkId, 'link_visible' => 'N', 'link_notes' => '已拒绝: ' . $reason, 'link_updated' => current_time('mysql')]);
        if ($link->link_owner) {
            $adapter = \XZD\AI\V5\Theme\AdapterRegistry::getCurrent();
            $adapter->sendNotification((int)$link->link_owner, '友链申请未通过', "您的友链«{$link->link_name}»未通过审核。原因：{$reason}", 1);
        }
        Logger::info('friend_link', "拒绝友链 #{$linkId} «{$link->link_name}» 原因: {$reason}");
        return ToolResult::success(['link_id' => $linkId, 'link_name' => $link->link_name], "友链«{$link->link_name}»已拒绝");
    }

    /** 白名单开关 */
    public static function toggleLinkWhitelist(array $params, int $userId): ToolResult
    {
        $linkId = (int)($params['link_id'] ?? 0);
        if (!$linkId) return ToolResult::error('请提供友链ID');

        $link = get_bookmark($linkId);
        if (!$link) return ToolResult::error('友链不存在');

        $current = (bool)get_link_meta($linkId, self::WHITELIST, true);
        $newState = !$current;
        update_link_meta($linkId, self::WHITELIST, $newState);

        // 加入白名单时清除丢失状态
        if ($newState) {
            update_link_meta($linkId, self::STATUS_META, 'whitelist');
            update_link_meta($linkId, self::FAIL_COUNT, 0);
            delete_link_meta($linkId, self::LOST_AT_META);
        }

        $msg = $newState ? "友链«{$link->link_name}»已加入白名单，跳过自动检测" : "友链«{$link->link_name}»已移出白名单";
        Logger::info('friend_link', $msg);
        return ToolResult::success(['link_id' => $linkId, 'is_whitelist' => $newState], $msg);
    }

    /** 手动验证单条友链 */
    public static function verifyFriendLink(array $params, int $userId): ToolResult
    {
        self::ensureBookmarkFunctions();
        $linkId = (int)($params['link_id'] ?? 0);
        if (!$linkId) return ToolResult::error('请提供友链ID');

        $link = get_bookmark($linkId);
        if (!$link) return ToolResult::error('友链不存在');

        // 白名单跳过
        if (get_link_meta($linkId, self::WHITELIST, true)) {
            return ToolResult::success(['link_id' => $linkId, 'link_name' => $link->link_name, 'status' => 'whitelist'], '该友链在白名单中，已跳过检测');
        }

        $result = self::checkReciprocal($link->link_url);
        self::updateLinkStatus($linkId, $result['status']);

        Logger::info('friend_link', "验证友链 #{$linkId} «{$link->link_name}» -> {$result['status']}");
        return ToolResult::success([
            'link_id'   => $linkId,
            'link_name' => $link->link_name,
            'link_url'  => $link->link_url,
            'status'    => $result['status'],
            'found_url' => $result['found_url'] ?? '',
            'message'   => $result['message'],
        ], $result['message']);
    }

    /** 批量检测所有已通过友链 - 只标记不删除 */
    public static function checkAllFriendLinks(array $params, int $userId): ToolResult
    {
        self::ensureBookmarkFunctions();
        $batchLimit = (int)($params['batch_limit'] ?? 20);

        $links = get_bookmarks(['hide_invisible' => false]);
        $approved = array_filter($links, fn($l) => $l->link_visible === 'Y');
        if (empty($approved)) {
            return ToolResult::success(['checked' => 0, 'ok' => 0, 'lost' => 0, 'uncertain' => 0], '没有需要检测的友链');
        }

        $batch = array_slice($approved, 0, $batchLimit);
        $ok = $lost = $uncertain = $skipped = 0;
        $details = [];

        foreach ($batch as $link) {
            // 白名单跳过
            if (get_link_meta($link->link_id, self::WHITELIST, true)) {
                $skipped++;
                $details[] = ['link_id' => $link->link_id, 'link_name' => $link->link_name, 'link_url' => $link->link_url, 'status' => 'whitelist'];
                continue;
            }

            $result = self::checkReciprocal($link->link_url);
            $details[] = [
                'link_id'   => $link->link_id,
                'link_name' => $link->link_name,
                'link_url'  => $link->link_url,
                'status'    => $result['status'],
            ];

            self::updateLinkStatus($link->link_id, $result['status']);

            if ($result['status'] === 'found') {
                $ok++;
            } elseif ($result['status'] === 'not_found') {
                $lost++;
                $failCount = (int)get_link_meta($link->link_id, self::FAIL_COUNT, true);

                // 连续失败达到阈值发通知，不删除
                if ($failCount >= self::LOST_ALERT_THRESHOLD) {
                    $firstLost = get_link_meta($link->link_id, self::LOST_AT_META, true) ?: '未知时间';
                    if (class_exists(RuleEngine::class)) {
                        RuleEngine::instance()->evaluateAsync('link_reciprocal_lost', [
                            'link_id'   => $link->link_id,
                            'link_url'  => $link->link_url,
                            'link_name' => $link->link_name,
                            'lost_at'   => $firstLost,
                        ]);
                    }
                    Logger::info('friend_link', "友链互链丢失(第{$failCount}次) #{$link->link_id} «{$link->link_name}» 首次丢失:{$firstLost}");
                } else {
                    Logger::info('friend_link', "友链检测未通过(第{$failCount}次) #{$link->link_id} «{$link->link_name}» -> {$result['status']}");
                }
            } else {
                $uncertain++;
            }
        }

        $msg = "检测" . count($batch) . "条：{$ok}正常, {$lost}丢失, {$uncertain}不确定";
        if ($skipped > 0) $msg .= ", {$skipped}白名单跳过";
        Logger::info('friend_link_monitor', $msg);

        return ToolResult::success([
            'checked'   => count($batch),
            'ok'        => $ok,
            'lost'      => $lost,
            'uncertain' => $uncertain,
            'skipped'   => $skipped,
            'details'   => $details,
        ], $msg);
    }

    /** cron入口 - 只标记不删除，自动检测受 monitor_enabled 开关控制 */
    public static function monitorAll(): void
    {
        self::ensureBookmarkFunctions();
        Logger::info('friend_link_monitor', '友链互审监控开始');
        $self = new self();
        $result = $self->checkAllFriendLinks(['batch_limit' => 20], 0);
        Logger::info('friend_link_monitor', '友链互审监控完成', ['summary' => $result->message]);
    }

    // 内部方法

    /**
     * 更新友链互链状态标记（只标记，不删除）
     */
    private static function updateLinkStatus(int $linkId, string $status): void
    {
        update_link_meta($linkId, self::STATUS_META, $status);

        if ($status === 'found') {
            update_link_meta($linkId, self::FAIL_COUNT, 0);
            delete_link_meta($linkId, self::LOST_AT_META);
        } elseif ($status === 'not_found') {
            $count = (int)get_link_meta($linkId, self::FAIL_COUNT, true) + 1;
            update_link_meta($linkId, self::FAIL_COUNT, $count);
            if ($count === 1) {
                update_link_meta($linkId, self::LOST_AT_META, current_time('mysql'));
            }
        }
        // uncertain: 不改变 fail_count
    }

    /**
     * 检测对方网站是否包含本站链接
     * body<500字符判为uncertain，防止验证页/CDN/WAF误判
     */
    private static function checkReciprocal(string $siteUrl): array
    {
        $ourDomain = parse_url(home_url(), PHP_URL_HOST);
        $siteUrl = rtrim($siteUrl, '/');

        $response = wp_remote_get($siteUrl, [
            'timeout'     => 15,
            'user-agent'  => 'XZD-AI-LinkChecker/1.0',
            'redirection' => 3,
        ]);

        if (is_wp_error($response)) {
            return [
                'status'  => 'uncertain',
                'error'   => $response->get_error_message(),
                'message' => "无法访问 {$siteUrl}: " . $response->get_error_message(),
            ];
        }

        $code = wp_remote_retrieve_response_code($response);
        if ($code !== 200) {
            return [
                'status'  => 'uncertain',
                'error'   => "HTTP {$code}",
                'message' => "{$siteUrl} 返回 HTTP {$code}",
            ];
        }

        $html = wp_remote_retrieve_body($response);
        $bodyText = strip_tags($html);
        $bodyLen = strlen(trim($bodyText));

        // body过短可能是验证页/CDN/WAF，判为uncertain
        if ($bodyLen < 500) {
            return [
                'status'  => 'uncertain',
                'message' => "对方网站返回内容过短({$bodyLen}字符)，可能是验证页面或CDN拦截，跳过判定",
            ];
        }

        // SPA检测
        if (preg_match('/<div\s+id=["\'](app|root)/i', $html)) {
            return [
                'status'  => 'uncertain',
                'message' => '对方网站为SPA单页应用，无法自动检测友链，请手动确认',
            ];
        }

        // 搜索本站链接
        $foundUrl = self::searchOurLink($html, $ourDomain);
        if ($foundUrl) {
            return [
                'status'    => 'found',
                'found_url' => $foundUrl,
                'message'   => "在 {$siteUrl} 找到本站链接",
            ];
        }

        return [
            'status'  => 'not_found',
            'message' => "在 {$siteUrl} 未找到本站链接",
        ];
    }

    /** @return array{title?: string, description?: string, favicon?: string, suggested_category?: string} */
    private static function fetchSiteInfo(string $url): array
    {
        $info = [];
        $response = wp_remote_get($url, [
            'timeout'     => 10,
            'user-agent'  => 'Mozilla/5.0 (compatible; XZD-AI-Fetcher/1.0)',
            'redirection' => 3,
        ]);
        if (is_wp_error($response)) return $info;
        $code = wp_remote_retrieve_response_code($response);
        if ($code !== 200) return $info;

        $html = wp_remote_retrieve_body($response);
        preg_match('/<title[^>]*>(.*?)<\/title>/is', $html, $titleMatch);
        if (!empty($titleMatch[1])) {
            $info['title'] = trim(preg_replace('/\s+/', ' ', html_entity_decode($titleMatch[1], ENT_QUOTES, 'UTF-8')));
        }
        preg_match('/<meta\s[^>]*name=["\']description["\'][^>]*content=["\']([^"\']+)["\']/is', $html, $descMatch);
        if (empty($descMatch)) {
            preg_match('/<meta\s[^>]*content=["\']([^"\']+)["\'][^>]*name=["\']description["\']/is', $html, $descMatch);
        }
        if (!empty($descMatch[1])) $info['description'] = trim($descMatch[1]);

        preg_match('/<link\s[^>]*rel=["\'](?:shortcut\s+)?icon["\'][^>]*href=["\']([^"\']+)["\']/is', $html, $iconMatch);
        if (empty($iconMatch)) {
            preg_match('/<link\s[^>]*href=["\']([^"\']+)["\'][^>]*rel=["\'](?:shortcut\s+)?icon["\']/is', $html, $iconMatch);
        }
        if (!empty($iconMatch[1])) {
            $favicon = $iconMatch[1];
            if (strpos($favicon, '//') === 0) $favicon = parse_url($url, PHP_URL_SCHEME) . ':' . $favicon;
            elseif (strpos($favicon, '/') === 0) $favicon = rtrim($url, '/') . $favicon;
            elseif (!preg_match('/^https?:\/\//', $favicon)) $favicon = rtrim($url, '/') . '/' . $favicon;
            $info['favicon'] = $favicon;
        } else {
            $info['favicon'] = rtrim($url, '/') . '/favicon.ico';
        }

        $bodyText = strip_tags($html);
        if (preg_match('/博客|blog|文章|写作/i', $bodyText) || preg_match('/blog/i', $url)) {
            $info['suggested_category'] = '博客';
        } elseif (preg_match('/论坛|社区|BBS|forum|社区/i', $bodyText) || preg_match('/forum|bbs/i', $url)) {
            $info['suggested_category'] = '社区论坛';
        } elseif (preg_match('/工具|tool|生成器|转换|下载/i', $bodyText)) {
            $info['suggested_category'] = '工具';
        } elseif (preg_match('/科技|技术|开发|编程|代码|AI/i', $bodyText)) {
            $info['suggested_category'] = '技术';
        } elseif (preg_match('/商城|购物|shop|store|商品/i', $bodyText)) {
            $info['suggested_category'] = '商业';
        }
        return $info;
    }

    /** 在HTML中搜索本站链接 */
    private static function searchOurLink(string $html, string $ourDomain): string
    {
        $cleanOur = preg_replace('/^www\./', '', $ourDomain);

        preg_match_all('/<a\s[^>]*href=["\']([^"\']+)["\'][^>]*>/i', $html, $matches);
        $hrefs = $matches[1] ?? [];

        foreach ($hrefs as $href) {
            $host = parse_url($href, PHP_URL_HOST);
            if ($host && strcasecmp(preg_replace('/^www\./', '', $host), $cleanOur) === 0) {
                return $href;
            }
            $targetUrl = self::extractRedirectTarget($href);
            if ($targetUrl) {
                $targetHost = parse_url($targetUrl, PHP_URL_HOST);
                if ($targetHost && strcasecmp(preg_replace('/^www\./', '', $targetHost), $cleanOur) === 0) {
                    return $href . ' -> ' . $targetUrl;
                }
            }
        }

        $patterns = [
            '/(?:url|to|goto|link|redirect|jump|target|dest)=?(https?%3A%2F%2F[^&\s"\']*' . preg_quote($ourDomain, '/') . '[^&\s"\']*)/i',
            '/(?:url|to|goto|link|redirect|jump|target|dest)=?(https?:\/\/[^&\s"\']*' . preg_quote($ourDomain, '/') . '[^&\s"\']*)/i',
        ];
        foreach ($patterns as $pattern) {
            if (preg_match($pattern, $html, $m)) {
                $decoded = urldecode($m[1]);
                return '(go跳转中找到本站: ' . $decoded . ')';
            }
        }

        return '';
    }

    /** 从go跳转URL中提取真实目标URL */
    private static function extractRedirectTarget(string $url): string
    {
        $parsed = parse_url($url);
        if (!$parsed) return '';

        if (!empty($parsed['query'])) {
            parse_str($parsed['query'], $params);
            foreach (['url', 'to', 'goto', 'link', 'redirect', 'jump', 'target', 'dest'] as $key) {
                if (!empty($params[$key]) && filter_var($params[$key], FILTER_VALIDATE_URL)) {
                    return $params[$key];
                }
            }
        }

        if (!empty($parsed['path']) && preg_match('/(?:go|goto|redirect|jump|link|out)\/(https?(?::\/|%3A%2F%2F)[^\s&]+)/i', $parsed['path'], $m)) {
            $decoded = urldecode($m[1]);
            if (filter_var($decoded, FILTER_VALIDATE_URL)) return $decoded;
        }

        return '';
    }
}
