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

function Mirai_hideGetPointsCost($attrs) {
    return isset($attrs['cost']) ? max(1, (int)$attrs['cost']) : 0;
}

function Mirai_hideCheckPoints($cid, $uid, $attrs, $widget, $index = 0) {
    if ($uid <= 0) {
        return ['allowed' => false, 'reason' => 'not_logged_in'];
    }

    $cost = Mirai_hideGetPointsCost($attrs);
    if ($cost <= 0) {
        return ['allowed' => false, 'reason' => 'cost_missing'];
    }

    if (!function_exists('Mirai_pointsEnabled') || !Mirai_pointsEnabled()) {
        return ['allowed' => false, 'reason' => 'points_system_disabled'];
    }

    $refId = $cid . '_' . $index;
    if (Mirai_hidePointsHasPaid($uid, $refId)) {
        return ['allowed' => true, 'reason' => 'already_paid'];
    }

    $balance = function_exists('Mirai_pointsGetBalance') ? Mirai_pointsGetBalance($uid) : 0;
    if ($balance < $cost) {
        return ['allowed' => false, 'reason' => 'insufficient_balance', 'balance' => $balance, 'cost' => $cost];
    }

    $unlock = isset($_POST['mirai_hide_points_unlock']) && (int)$_POST['mirai_hide_points_unlock'] === $cid && isset($_POST['mirai_hide_points_idx']) && (int)$_POST['mirai_hide_points_idx'] === $index;
    if (!$unlock) {
        return ['allowed' => false, 'reason' => 'need_confirm', 'balance' => $balance, 'cost' => $cost];
    }

    // CSRF token verification for points deduction
    $security = \Widget\Security::alloc();
    $postToken = isset($_POST['_mirai_token']) ? (string)$_POST['_mirai_token'] : '';
    if ($postToken === '' || !hash_equals($security->getToken('api'), $postToken)) {
        return ['allowed' => false, 'reason' => 'deduct_failed', 'msg' => '安全验证失败，请刷新页面重试'];
    }

    // Prevent double-submission via session nonce
    if (session_status() === PHP_SESSION_NONE) {
        @session_start();
    }
    $nonceKey = 'mirai_points_nonce_' . $cid . '_' . $index;
    $submittedNonce = isset($_POST['_mirai_nonce']) ? (string)$_POST['_mirai_nonce'] : '';
    if ($submittedNonce !== '' && isset($_SESSION[$nonceKey]) && hash_equals($_SESSION[$nonceKey], $submittedNonce)) {
        unset($_SESSION[$nonceKey]);
    } elseif ($submittedNonce !== '') {
        return ['allowed' => false, 'reason' => 'deduct_failed', 'msg' => '请勿重复提交，请刷新页面重试'];
    }

    if (!function_exists('Mirai_pointsAdjust')) {
        return ['allowed' => false, 'reason' => 'system_error'];
    }

    $pointsName = function_exists('Mirai_pointsName') ? Mirai_pointsName() : '积分';
    $result = Mirai_pointsAdjust($uid, -$cost, 'hide_content_spend', 'hide_content', $refId, '消耗' . $cost . $pointsName . '查看隐藏内容');

    if (!$result['success']) {
        return ['allowed' => false, 'reason' => 'deduct_failed', 'msg' => isset($result['msg']) ? $result['msg'] : ''];
    }

    return ['allowed' => true, 'reason' => 'just_paid'];
}

function Mirai_hidePointsHasPaid($uid, $refId) {
    $db = \Typecho\Db::get();
    $logTable = Mirai_pointsTable('mirai_points_logs');
    try {
        $row = $db->fetchRow($db->select('id')->from($logTable)
            ->where('uid = ? AND action = ? AND ref_type = ? AND ref_id = ? AND amount < 0', $uid, 'hide_content_spend', 'hide_content', $refId)
            ->limit(1));
        return !empty($row);
    } catch (\Exception $e) {
        return false;
    }
}
