<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;

function Mirai_hideTypeEnabled($type) {
    $autoDisabled = [
        'vip'     => function_exists('Mirai_vipEnabled') && !Mirai_vipEnabled(),
        'level'   => function_exists('Mirai_levelEnabled') && !Mirai_levelEnabled(),
        'points'  => function_exists('Mirai_pointsEnabled') && !Mirai_pointsEnabled(),
    ];
    if (isset($autoDisabled[$type]) && $autoDisabled[$type]) return false;
    return true;
}

function Mirai_hideFilterContent($content, $widget, $uid) {
    $content = (string)$content;
    $cid = isset($widget->cid) ? (int)$widget->cid : 0;
    $authorId = isset($widget->authorId) ? (int)$widget->authorId : 0;
    $isAuthor = $uid > 0 && $uid === $authorId;
    $isAdmin = false;
    if ($uid > 0) {
        $user = Mirai_user();
        if (method_exists($user, 'pass') && $user->pass('administrator', true)) {
            $isAdmin = true;
        }
    }

    $content = preg_replace_callback('/\[\[(hide(?:\s+[^\]]*)?)\]\]/i', function($m) {
        return "\x00MIRAI_HIDE_ESCAPED_OPEN_" . $m[1] . "\x00";
    }, $content);
    $content = preg_replace('/\[\[\/hide\]\]/i', "\x00MIRAI_HIDE_ESCAPED_CLOSE\x00", $content);

    $content = preg_replace('/<p>\s*\[hide(\s+[^\]]*?)?\]\s*<\/p>/i', '[hide$1]', $content);
    $content = preg_replace('/<p>\s*\[\/hide\]\s*<\/p>/i', '[/hide]', $content);

    $protectedAreas = [];
    $protectPattern = '/(<(code|pre|kbd)[^>]*>[\s\S]*?<\/\2>|<table[\s\S]*?<\/table>)/i';
    $content = preg_replace_callback($protectPattern, function($matches) use (&$protectedAreas) {
        $placeholder = "\x00MIRAI_HIDE_PROTECTED_" . count($protectedAreas) . "\x00";
        $protectedAreas[] = $matches[0];
        return $placeholder;
    }, $content);

    $pattern = '/\[hide(?:\s+([^\]]*))?\]([\s\S]*?)\[\/hide\]/i';

    $hideIndex = 0;
    $content = preg_replace_callback($pattern, function($matches) use ($cid, $uid, $isAuthor, $isAdmin, $widget, &$hideIndex) {
        $attrStr = isset($matches[1]) ? $matches[1] : '';
        $innerContent = $matches[2];
        $currentIndex = $hideIndex++;

        $attrs = Mirai_hideParseAttrs($attrStr);
        $type = isset($attrs['type']) ? strtolower(trim($attrs['type'])) : 'reply';

        if (!Mirai_hideTypeEnabled($type)) {
            // 系统禁用时直接展示内容，不再限制访问
            return $innerContent;
        }

        if ($isAuthor || $isAdmin) {
            return $innerContent;
        }

        $checker = Mirai_hideGetChecker($type);
        if (!$checker) {
            return $innerContent;
        }

        $result = call_user_func($checker, $cid, $uid, $attrs, $widget, $currentIndex);

        if (isset($result['allowed']) && $result['allowed']) {
            return $innerContent;
        }

        return Mirai_hideRenderLocked($type, $attrs, $result, $cid, $uid, $currentIndex, $widget);
    }, $content);

    foreach ($protectedAreas as $index => $original) {
        $content = str_replace("\x00MIRAI_HIDE_PROTECTED_" . $index . "\x00", $original, $content);
    }

    $content = preg_replace_callback('/\x00MIRAI_HIDE_ESCAPED_OPEN_(hide(?:\s+[^\]\x00]*)?)\x00/i', function($m) {
        return '[' . $m[1] . ']';
    }, $content);
    $content = str_replace("\x00MIRAI_HIDE_ESCAPED_CLOSE\x00", '[/hide]', $content);

    return ['content' => $content];
}

function Mirai_hideParseAttrs($attrStr) {
    $attrs = [];
    $attrStr = trim($attrStr);
    if ($attrStr === '') return $attrs;

    // 双引号属性
    preg_match_all('/(\w+)\s*=\s*"([^"]*)"/', $attrStr, $m, PREG_SET_ORDER);
    foreach ($m as $match) {
        $attrs[$match[1]] = $match[2];
    }

    // 单引号属性
    preg_match_all("/(\w+)\s*=\s*'([^']*)'/", $attrStr, $m2, PREG_SET_ORDER);
    foreach ($m2 as $match) {
        $attrs[$match[1]] = $match[2];
    }

    // 无引号属性（如 type=reply）
    preg_match_all('/(\w+)\s*=\s*([^\s\]]+)/', $attrStr, $m3, PREG_SET_ORDER);
    foreach ($m3 as $match) {
        if (!isset($attrs[$match[1]])) {
            $attrs[$match[1]] = $match[2];
        }
    }

    return $attrs;
}

function Mirai_hideGetChecker($type) {
    static $checkers = null;
    if ($checkers === null) {
        $checkers = [
            'reply'   => 'Mirai_hideCheckReply',
            'login'   => 'Mirai_hideCheckLogin',
            'vip'     => 'Mirai_hideCheckVip',
            'password' => 'Mirai_hideCheckPassword',
            'level'   => 'Mirai_hideCheckLevel',
            'points'  => 'Mirai_hideCheckPoints',
        ];
    }
    return isset($checkers[$type]) && function_exists($checkers[$type]) ? $checkers[$type] : null;
}

function Mirai_hideTypeLabel($type) {
    $labels = [
        'reply'   => '评论可见',
        'login'   => '登录可见',
        'vip'     => '会员可见',
        'password' => '密码验证',
        'level'   => '等级可见',
        'points'  => '积分可见',
    ];
    return isset($labels[$type]) ? $labels[$type] : '隐藏内容';
}
