<?php

namespace CaptureRelay;

final class Cron
{
    public const HOOK = 'capture_relay_cleanup';

    public static function schedule(): void
    {
        if (!wp_next_scheduled(self::HOOK)) {
            wp_schedule_event(time() + HOUR_IN_SECONDS, 'hourly', self::HOOK);
        }
    }

    public static function unschedule(): void
    {
        $timestamp = wp_next_scheduled(self::HOOK);
        if ($timestamp) {
            wp_unschedule_event($timestamp, self::HOOK);
        }
    }

    public static function cleanup(): void
    {
        global $wpdb;
        $now = current_time('mysql', true);
        $wpdb->query($wpdb->prepare(
            "UPDATE %i SET status = 'expired', ip_address = '' WHERE status = 'pending' AND expires_at < %s",
            Config::table('requests'),
            $now
        ));
        $expiredDevices = $wpdb->get_col($wpdb->prepare(
            "SELECT device_id FROM %i WHERE status = 'approved' AND completed_at IS NULL AND expires_at < %s",
            Config::table('requests'),
            $now
        ));
        foreach ($expiredDevices as $deviceId) {
            $wpdb->update(Config::table('devices'), [
                'status' => 'revoked',
                'credential_cipher' => CredentialVault::seal(Security::randomToken(48)),
                'revoked_at' => $now,
            ], ['device_id' => $deviceId], ['%s', '%s', '%s'], ['%s']);
        }
        $wpdb->query($wpdb->prepare(
            "UPDATE %i SET status = 'expired', credential_envelope = NULL, envelope_expires_at = NULL, ip_address = '' WHERE status = 'approved' AND completed_at IS NULL AND expires_at < %s",
            Config::table('requests'),
            $now
        ));
        $wpdb->query($wpdb->prepare('DELETE FROM %i WHERE expires_at < %s', Config::table('nonces'), $now));

        $requestCutoff = gmdate('Y-m-d H:i:s', time() - ((int) Config::get('request_retention_days', 30) * DAY_IN_SECONDS));
        $wpdb->query($wpdb->prepare(
            "DELETE FROM %i WHERE ((status IN ('expired','rejected','cancelled')) OR (status = 'approved' AND completed_at IS NOT NULL)) AND created_at < %s",
            Config::table('requests'),
            $requestCutoff
        ));
        $uploadCutoff = gmdate('Y-m-d H:i:s', time() - ((int) Config::get('upload_record_retention_days', 90) * DAY_IN_SECONDS));
        $wpdb->query($wpdb->prepare('DELETE FROM %i WHERE created_at < %s', Config::table('uploads'), $uploadCutoff));
        $activityCutoff = gmdate('Y-m-d H:i:s', time() - ((int) Config::get('activity_retention_days', 90) * DAY_IN_SECONDS));
        $wpdb->query($wpdb->prepare('DELETE FROM %i WHERE created_at < %s', Config::table('activity'), $activityCutoff));
        $wpdb->query($wpdb->prepare('DELETE FROM %i WHERE expires_at < %s', Config::table('rate_limits'), $now));
    }
}
