<?php

namespace XZD\AI\V5\Core;

/**
 * 文章日期保护器 — 防止 AI 自动处理篡改 post_modified
 *
 * 背景：wp_update_post() 默认自动更新 post_modified 为当前时间。
 * 当 AI 批量处理历史文章时，post_modified 被静默更新会导致旧文章跳到首页。
 *
 * 用法：
 *   // AI 自动处理（保护原始日期）
 *   PreserveDates::updatePost(['ID'=>82, 'post_content'=>'...']);
 *   // 用户手动操作（正常更新日期）
 *   PreserveDates::updatePost(['ID'=>82, 'post_title'=>'...'], true);
 */
class PreserveDates
{
    /** 全局日期保护开关 — 流水线/批量/自动化处理期间强制保护日期 */
    private static bool $protecting = false;

    /** DB级别的原始日期缓存 — post_id => [post_date, post_date_gmt, post_modified, post_modified_gmt] */
    private static array $capturedDates = [];

    /**
     * 初始化过滤器（由 Plugin 启动时调用一次）
     */
    public static function init(): void
    {
        add_filter('wp_insert_post_data', [self::class, 'filterPostData'], 999, 2);
    }

    /**
     * 开启全局日期保护（流水线/批量/自动化处理入口调用）
     */
    public static function startProtection(): void
    {
        self::$protecting = true;
    }

    /**
     * 关闭全局日期保护
     */
    public static function endProtection(): void
    {
        self::$protecting = false;
    }

    /**
     * 从数据库捕获文章的原始日期（DB级别保护）
     *
     * 与 filterPostData() 互补：filterPostData 拦截 wp_update_post 路径，
     * 此方法在操作前直接用 SELECT 读取日期，操作后 verifyAndRestore 比对恢复。
     * 防止 $wpdb->update() 直接调用或 MySQL ON UPDATE CURRENT_TIMESTAMP 绕过过滤器。
     */
    public static function captureDates(int $postId): void
    {
        global $wpdb;
        $row = $wpdb->get_row($wpdb->prepare(
            "SELECT post_date, post_date_gmt, post_modified, post_modified_gmt
             FROM {$wpdb->posts} WHERE ID = %d", $postId
        ), ARRAY_A);
        if ($row) {
            self::$capturedDates[$postId] = $row;
        }
    }

    /**
     * 验证并恢复被篡改的文章日期
     *
     * @return bool true=日期被恢复, false=日期未变化
     */
    public static function verifyAndRestore(int $postId): bool
    {
        if (!isset(self::$capturedDates[$postId])) {
            return false;
        }
        $original = self::$capturedDates[$postId];

        global $wpdb;
        $current = $wpdb->get_row($wpdb->prepare(
            "SELECT post_date, post_date_gmt, post_modified, post_modified_gmt
             FROM {$wpdb->posts} WHERE ID = %d", $postId
        ), ARRAY_A);
        if (!$current) {
            unset(self::$capturedDates[$postId]);
            return false;
        }

        $changed = false;
        foreach (['post_date', 'post_date_gmt', 'post_modified', 'post_modified_gmt'] as $col) {
            if ($current[$col] !== $original[$col]) {
                $changed = true;
                break;
            }
        }

        if ($changed) {
            $wpdb->update($wpdb->posts, $original, ['ID' => $postId]);
            clean_post_cache($postId);
            unset(self::$capturedDates[$postId]);
            return true;
        }

        unset(self::$capturedDates[$postId]);
        return false;
    }

    /**
     * wp_insert_post_data 过滤器 — 安全网：拦截所有 wp_update_post/wp_insert_post，
     * 当保护开关开启时强制保留原始日期字段
     */
    public static function filterPostData(array $data, array $postarr): array
    {
        if (!self::$protecting || empty($data['ID'])) {
            return $data;
        }
        $post = get_post($data['ID']);
        if (!$post) {
            return $data;
        }
        $data['post_date']         = $post->post_date;
        $data['post_date_gmt']     = $post->post_date_gmt;
        $data['post_modified']     = $post->post_modified;
        $data['post_modified_gmt'] = $post->post_modified_gmt;
        return $data;
    }

    /**
     * 更新文章，保护或更新 post_modified
     *
     * @param array $data           wp_update_post 的参数
     * @param bool  $isManualAction 是否用户手动操作（true=更新日期, false=保护日期）
     * @return int|\WP_Error        wp_update_post 返回值
     */
    public static function updatePost(array $data, bool $isManualAction = false): int|\WP_Error
    {
        if (empty($data['ID'])) {
            return 0;
        }

        $post = get_post($data['ID']);
        if (!$post) {
            return 0;
        }

        if (!$isManualAction) {
            // AI 自动处理：DB级别保护 — 操作前捕获原始日期
            self::captureDates($data['ID']);

            // 显式保留原始日期，防止旧文章跳到首页
            if (!isset($data['post_date'])) {
                $data['post_date'] = $post->post_date;
            }
            if (!isset($data['post_date_gmt'])) {
                $data['post_date_gmt'] = $post->post_date_gmt;
            }
            if (!isset($data['post_modified'])) {
                $data['post_modified'] = $post->post_modified;
            }
            if (!isset($data['post_modified_gmt'])) {
                $data['post_modified_gmt'] = $post->post_modified_gmt;
            }
        }
        // 用户手动操作：不传 post_modified，让 WordPress 自动更新为当前时间

        $result = wp_update_post($data, true);

        // AI 自动处理：操作后DB级别验证恢复
        if (!$isManualAction && !is_wp_error($result)) {
            self::verifyAndRestore($data['ID']);
        }

        return $result;
    }
}
