<?php
/**
 * Cron and expiry checking functionality
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class BW_Expiry_Cron {

    private static $instance = null;
    private $meta_key = '_bw_expiry_date';

    public static function get_instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {
        // Hook into WP-Cron scheduled event
        add_action( 'bw_expiry_check_posts', array( $this, 'check_expired_posts' ) );

        // Also check on init for immediate expiry (runs on every page load)
        add_action( 'wp', array( $this, 'check_expired_posts_frontend' ) );

        // Check on admin init as well
        add_action( 'admin_init', array( $this, 'check_expired_posts' ) );

        // Prevent viewing expired posts (extra safety)
        add_action( 'template_redirect', array( $this, 'maybe_redirect_expired' ) );
    }

    /**
     * Check for expired posts (cron/admin)
     */
    public function check_expired_posts() {
        $this->process_expired_posts();
    }

    /**
     * Check for expired posts on frontend
     * Rate limited to prevent performance issues
     */
    public function check_expired_posts_frontend() {
        // Only run once per minute on frontend
        $last_check = get_transient( 'bw_expiry_last_frontend_check' );
        if ( $last_check ) {
            return;
        }

        set_transient( 'bw_expiry_last_frontend_check', time(), MINUTE_IN_SECONDS );
        $this->process_expired_posts();
    }

    /**
     * Process and expire posts
     */
    private function process_expired_posts() {
        $options = get_option( 'bw_expiry_settings', array() );
        $enabled_types = isset( $options['post_types'] ) ? $options['post_types'] : array( 'post' );

        // Current time in MySQL format
        $current_time = current_time( 'mysql' );

        // Query for published posts with expiry dates in the past
        $args = array(
            'post_type'      => $enabled_types,
            'post_status'    => 'publish',
            'posts_per_page' => 50, // Process in batches
            'meta_query'     => array(
                array(
                    'key'     => $this->meta_key,
                    'value'   => $current_time,
                    'compare' => '<=',
                    'type'    => 'DATETIME',
                ),
            ),
            'fields'         => 'ids', // Only get IDs for performance
        );

        $expired_posts = get_posts( $args );

        foreach ( $expired_posts as $post_id ) {
            $this->expire_post( $post_id );
        }

        // Log if any posts were expired
        if ( ! empty( $expired_posts ) ) {
            error_log( sprintf(
                '[BW Expiry Post] Expired %d posts: %s',
                count( $expired_posts ),
                implode( ', ', $expired_posts )
            ) );
        }
    }

    /**
     * Expire a single post
     */
    private function expire_post( $post_id ) {
        // Double-check post is still published
        $post = get_post( $post_id );
        if ( ! $post || $post->post_status !== 'publish' ) {
            return;
        }

        // Set to draft
        wp_update_post( array(
            'ID'          => $post_id,
            'post_status' => 'draft',
        ) );

        // Mark as expired by this plugin
        update_post_meta( $post_id, '_bw_expired', true );
        update_post_meta( $post_id, '_bw_expired_date', current_time( 'mysql' ) );

        // Fire action for extensibility
        do_action( 'bw_expiry_post_expired', $post_id, $post );
    }

    /**
     * Redirect if trying to view an expired post directly
     * This catches edge cases where the post hasn't been processed yet
     */
    public function maybe_redirect_expired() {
        if ( is_admin() || ! is_singular() ) {
            return;
        }

        $post = get_queried_object();
        if ( ! $post || ! is_a( $post, 'WP_Post' ) ) {
            return;
        }

        // Check if post type is enabled
        $plugin = BW_Expiry_Post::get_instance();
        if ( ! $plugin->is_post_type_enabled( $post->post_type ) ) {
            return;
        }

        // Check if post has expiry date
        $expiry_date = get_post_meta( $post->ID, $this->meta_key, true );

        if ( empty( $expiry_date ) ) {
            return;
        }

        // Check if expired
        $expiry_timestamp = strtotime( $expiry_date );
        $current_timestamp = current_time( 'timestamp' );

        if ( $expiry_timestamp && $expiry_timestamp <= $current_timestamp ) {
            // Post is expired - expire it now and redirect
            $this->expire_post( $post->ID );

            // Redirect to homepage with a notice
            wp_redirect( home_url( '/' ) );
            exit;
        }
    }
}
