<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ — NUCLEAR+++
// File: /home/ploi/automarketer-ai.com/public/wp-content/plugins/automarketer-ai/includes/class-media-cleanup.php
// Description: Daily cron that deletes unattached media library attachments older than 24 hours - NUCLEAR+++
// Last Edited: 2026-05-03
// ==================================================

namespace AutoMarketerAI;

if (!defined('ABSPATH')) {
    exit('No direct script access allowed.');
}

final class MediaCleanup
{
    private const CRON_HOOK = 'amai_media_cleanup_daily';
    private const MIN_AGE   = 86400; // 24 hours in seconds

    // ---------------------------------------------------------------------------
    // Boot
    // ---------------------------------------------------------------------------

    public static function init(): void
    {
        add_action(self::CRON_HOOK, [self::class, 'run']);

        if (!wp_next_scheduled(self::CRON_HOOK)) {
            wp_schedule_event(time(), 'daily', self::CRON_HOOK);
        }
    }

    public static function scheduleDaily(): void
    {
        if (!wp_next_scheduled(self::CRON_HOOK)) {
            wp_schedule_event(time(), 'daily', self::CRON_HOOK);
        }
    }

    public static function clearSchedule(): void
    {
        $timestamp = wp_next_scheduled(self::CRON_HOOK);
        if ($timestamp !== false) {
            wp_unschedule_event($timestamp, self::CRON_HOOK);
        }
    }

    // ---------------------------------------------------------------------------
    // Main runner — called by daily cron
    // ---------------------------------------------------------------------------

    public static function run(): void
    {
        $cutoff = gmdate('Y-m-d H:i:s', time() - self::MIN_AGE);

        $attachments = get_posts([
            'post_type'      => 'attachment',
            'post_status'    => 'inherit',
            'post_parent'    => 0,
            'posts_per_page' => -1,
            'date_query'     => [
                [
                    'column' => 'post_date_gmt',
                    'before' => $cutoff,
                ],
            ],
            'fields'         => 'ids',
        ]);

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

        // Build protected sets once — cheaper than per-attachment queries.
        $featured_ids   = self::getFeaturedImageIds();
        $scheduled_ids  = self::getScheduledPostAttachmentIds();
        $scheduled_urls = self::getScheduledPostImageUrls();

        foreach ($attachments as $id) {
            $id = (int) $id;

            // Never delete attachments used as featured images.
            if (isset($featured_ids[$id])) {
                continue;
            }

            // Never delete attachments referenced in any scheduled social post.
            if (isset($scheduled_ids[$id])) {
                continue;
            }

            // Never delete attachments whose URL appears in scheduled post image URLs.
            $url = wp_get_attachment_url($id);
            if ($url !== false && $url !== '' && isset($scheduled_urls[$url])) {
                continue;
            }

            // Never delete attachments referenced in any post content.
            if ($url !== false && $url !== '' && self::isReferencedInContent($url)) {
                continue;
            }

            wp_delete_attachment($id, true);
        }
    }

    // ---------------------------------------------------------------------------
    // Build a map of attachment IDs currently set as featured images.
    // ---------------------------------------------------------------------------

    private static function getFeaturedImageIds(): array
    {
        global $wpdb;

        $rows = $wpdb->get_col(
            "SELECT DISTINCT meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_thumbnail_id'"
        );

        $map = [];
        foreach ($rows as $val) {
            $map[(int) $val] = true;
        }

        return $map;
    }

    // ---------------------------------------------------------------------------
    // Build a map of attachment IDs referenced in wp_amai_scheduled_posts.
    // ---------------------------------------------------------------------------

    private static function getScheduledPostAttachmentIds(): array
    {
        global $wpdb;

        $rows = $wpdb->get_col(
            "SELECT DISTINCT unsplash_attachment_id FROM {$wpdb->prefix}amai_scheduled_posts WHERE unsplash_attachment_id IS NOT NULL"
        );

        $map = [];
        foreach ($rows as $val) {
            $map[(int) $val] = true;
        }

        return $map;
    }

    // ---------------------------------------------------------------------------
    // Build a map of image URLs referenced in wp_amai_scheduled_posts.
    // ---------------------------------------------------------------------------

    private static function getScheduledPostImageUrls(): array
    {
        global $wpdb;

        $rows = $wpdb->get_col(
            "SELECT DISTINCT post_image_url FROM {$wpdb->prefix}amai_scheduled_posts WHERE post_image_url IS NOT NULL AND post_image_url != ''"
        );

        $map = [];
        foreach ($rows as $val) {
            $map[(string) $val] = true;
        }

        return $map;
    }

    // ---------------------------------------------------------------------------
    // Check whether an attachment URL appears in any post content.
    // ---------------------------------------------------------------------------

    private static function isReferencedInContent(string $url): bool
    {
        global $wpdb;

        $count = (int) $wpdb->get_var(
            $wpdb->prepare(
                "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_status != 'trash' AND post_content LIKE %s",
                '%' . $wpdb->esc_like($url) . '%'
            )
        );

        return $count > 0;
    }
}