<?php

namespace XZD\AI\V5\Core;

/**
 * 统一通知限流器 — 每种通知每天最多发送 3 次
 *
 * 使用 wp_options 记录当天每类通知已发次数，跨天自动归零。
 * key 格式: xzd_notify_{type}_{date}
 */
class NotificationThrottle
{
    const MAX_PER_DAY = 3;

    /**
     * 发送通知（自动节流）
     *
     * @param string $type    通知类型标识（如 'ai_all_failed', 'write_article_failed'）
     * @param string $subject 邮件标题
     * @param string $message 邮件正文
     * @return bool 是否实际发送了通知
     */
    public static function send(string $type, string $subject, string $message): bool
    {
        $date = date('Y-m-d');
        $key = "xzd_notify_{$type}_{$date}";

        // 原子递增计数（防止并发超发），MySQL INSERT ... ON DUPLICATE KEY UPDATE
        global $wpdb;
        $optName = $wpdb->options;
        $wpdb->query($wpdb->prepare(
            "INSERT INTO {$optName} (option_name, option_value, autoload)
             VALUES (%s, %d, 'no')
             ON DUPLICATE KEY UPDATE option_value = option_value + 1",
            $key, 1
        ));

        // 读取当前计数判断是否超限（递增后的值可能略超 MAX，用 >= 比较即可）
        $count = (int) get_option($key, 0);
        if ($count > self::MAX_PER_DAY) {
            return false;
        }

        $siteName = get_bloginfo('name');
        $fullSubject = "[{$siteName}] {$subject}";

        // 异步发送（原同步 wp_mail 在 Worker/心跳路径可能阻塞10-30s）
        if (function_exists('as_schedule_single_action')) {
            as_schedule_single_action(
                time() + 1,
                'xzd_async_send_notification',
                [['subject' => $fullSubject, 'message' => $message]],
                'xzd_notify'
            );
            return true;
        }

        // AS 不可用时降级为同步发送
        self::doSend($fullSubject, $message);
        return true;
    }

    /**
     * 实际发送逻辑（供 AS 异步回调或同步降级调用）
     */
    public static function doSend(string $fullSubject, string $message): void
    {
        wp_mail(get_option('admin_email'), $fullSubject, $message);

        // 通过适配器发送站内通知（三层降级：ZibMsg → zib_message表 → user_meta）
        $adminIds = get_users(['role' => 'administrator', 'fields' => 'ID']);
        if (!empty($adminIds)) {
            $adapter = \XZD\AI\V5\Theme\AdapterRegistry::getCurrent();
            if ($adapter) {
                $adapter->sendBulkNotification($adminIds, $fullSubject, nl2br(esc_html($message)), 0);
            }
        }
    }

    /**
     * 清理过期通知计数（保留30天，防止 wp_options 表膨胀）
     * 由每日清理 cron 调用
     */
    public static function cleanExpired(): int
    {
        global $wpdb;
        $cutoff = date('Y-m-d', strtotime('-30 days'));
        $pattern = $wpdb->esc_like('xzd_notify_') . '%';
        $deleted = $wpdb->query($wpdb->prepare(
            "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s AND option_name < %s",
            $pattern, 'xzd_notify_' . $cutoff
        ));
        return (int) $deleted;
    }
}
