<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ — NUCLEAR+++
// File: /home/ploi/automarketer-ai.com/public/wp-content/plugins/automarketer-ai/includes/class-bounce-handler.php
// Description: Polls Elastic Email suppression API every 5 minutes for hard bounces, logs and notifies admin - NUCLEAR+++
// Last Edited: 2026-04-18
// ==================================================
namespace AutoMarketerAI;

defined('ABSPATH') || exit;

final class BounceHandler
{
    private const CRON_HOOK      = 'amai_bounce_poll';
    private const INTERVAL        = 'amai_five_minutes';
    private const ELASTIC_API_URL = 'https://api.elasticemail.com/v4/suppressions/bounces';
    // ADMIN_EMAIL removed -- use get_option('admin_email') at runtime
    private const BATCH_LIMIT     = 100;

    public static function register(): void
    {
        add_filter('cron_schedules', [self::class, 'addCronInterval']);
        add_action(self::CRON_HOOK,  [self::class, 'poll']);

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

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

    public static function addCronInterval(array $schedules): array
    {
        $schedules[self::INTERVAL] = [
            'interval' => 300,
            'display'  => 'Every 5 minutes',
        ];
        return $schedules;
    }

    // Called by cron -- fetches bounce list from Elastic Email, processes new hard bounces.
    public static function poll(): void
    {
        $api_key = KeyVault::decrypt((string) get_option('amai_api_key_email-elastic', ''));
        if ($api_key === '') {
            error_log('[AMAI] bounce_poll_skipped: email-elastic module not activated');
            return;
        }

        $bounces = self::fetchBounces($api_key);
        if ($bounces === null) {
            return;
        }

        foreach ($bounces as $bounce) {
            $email = isset($bounce['Email']) ? sanitize_email((string) $bounce['Email']) : '';
            if ($email === '') {
                continue;
            }
            if (self::alreadyLogged($email)) {
                continue;
            }
            self::logBounce($email);
            self::notifyAdmin($email);
        }
    }

    // Fetch bounce list from Elastic Email suppressions API.
    private static function fetchBounces(string $api_key): ?array
    {
        $url = add_query_arg([
            'limit'  => self::BATCH_LIMIT,
            'offset' => 0,
        ], self::ELASTIC_API_URL);

        $response = wp_remote_get($url, [
            'timeout' => 15,
            'headers' => [
                'X-ElasticEmail-ApiKey' => $api_key,
                'Content-Type'          => 'application/json',
            ],
        ]);

        if (is_wp_error($response)) {
            error_log('[AMAI] bounce_poll_request_failed: ' . $response->get_error_message());
            return null;
        }

        $code = wp_remote_retrieve_response_code($response);
        if ($code !== 200) {
            error_log('[AMAI] bounce_poll_non_200: ' . $code);
            return null;
        }

        $body    = wp_remote_retrieve_body($response);
        $decoded = json_decode($body, true);

        if (!is_array($decoded)) {
            error_log('[AMAI] bounce_poll_bad_response');
            return null;
        }

        return $decoded;
    }

    // Check if email already exists in wp_amai_bounces.
    private static function alreadyLogged(string $email): bool
    {
        global $wpdb;
        $count = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT COUNT(*) FROM {$wpdb->prefix}amai_bounces WHERE email = %s LIMIT 1",
                $email
            )
        );
        return (int) $count > 0;
    }

    private static function logBounce(string $email): void
    {
        global $wpdb;
        $wpdb->query(
            $wpdb->prepare(
                "INSERT INTO {$wpdb->prefix}amai_bounces (email, bounce_type, raw_status, bounced_at)
                 VALUES (%s, %s, %s, %s)",
                $email,
                'hard',
                'suppressed',
                gmdate('Y-m-d H:i:s')
            )
        );
    }

    private static function notifyAdmin(string $email): void
    {
        $website    = self::lookupWebsite($email);
        $bounced_at = gmdate('Y-m-d H:i:s') . ' UTC';
        $subject    = '[AutoMarketer AI] Hard Bounce - ' . $email;

        ob_start();
        ?>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"></head>
<body style="margin:0;padding:0;background:#F9FAFB;font-family:DM Sans,sans-serif;">
<table width="100%" cellpadding="0" cellspacing="0" style="background:#F9FAFB;padding:40px 0;">
  <tr><td align="center">
    <table width="560" cellpadding="0" cellspacing="0" style="background:#fff;border-radius:16px;border:1.5px solid #E7DDD5;overflow:hidden;">
      <tr><td style="background:#D97757;padding:24px 32px;">
        <p style="margin:0;font-family:Nunito,sans-serif;font-size:20px;font-weight:800;color:#fff;">AutoMarketer AI</p>
        <p style="margin:4px 0 0;font-size:13px;color:rgba(255,255,255,0.85);">Hard Bounce Notification</p>
      </td></tr>
      <tr><td style="padding:32px;">
        <p style="margin:0 0 24px;font-size:15px;color:#374151;">A customer email hard bounced. They may not have received their welcome email or license key.</p>
        <table width="100%" cellpadding="0" cellspacing="0" style="border:1.5px solid #E7DDD5;border-radius:10px;overflow:hidden;">
          <tr style="background:#F9FAFB;">
            <td style="padding:12px 16px;font-size:13px;font-weight:600;color:#6B7280;width:140px;">Customer Email</td>
            <td style="padding:12px 16px;font-size:14px;color:#111827;"><?php echo esc_html($email); ?></td>
          </tr>
          <tr>
            <td style="padding:12px 16px;font-size:13px;font-weight:600;color:#6B7280;border-top:1px solid #E7DDD5;">Website</td>
            <td style="padding:12px 16px;font-size:14px;color:#111827;border-top:1px solid #E7DDD5;"><?php echo esc_html($website ?: 'Not provided'); ?></td>
          </tr>
          <tr style="background:#F9FAFB;">
            <td style="padding:12px 16px;font-size:13px;font-weight:600;color:#6B7280;border-top:1px solid #E7DDD5;">Bounce Type</td>
            <td style="padding:12px 16px;font-size:14px;color:#111827;border-top:1px solid #E7DDD5;">Hard</td>
          </tr>
          <tr>
            <td style="padding:12px 16px;font-size:13px;font-weight:600;color:#6B7280;border-top:1px solid #E7DDD5;">Detected At</td>
            <td style="padding:12px 16px;font-size:14px;color:#111827;border-top:1px solid #E7DDD5;"><?php echo esc_html($bounced_at); ?></td>
          </tr>
        </table>
        <p style="margin:24px 0 0;font-size:13px;color:#6B7280;">Follow up with the customer directly to confirm they received their license key and download link.</p>
      </td></tr>
    </table>
  </td></tr>
</table>
</body>
</html>
        <?php
        $body = ob_get_clean();

        add_filter('wp_mail_content_type', static fn() => 'text/html');
        wp_mail((string) get_option('admin_email', ''), $subject, (string) $body);
        remove_all_filters('wp_mail_content_type');
    }

    // Look up website_url from business profile by matching WP user email.
    private static function lookupWebsite(string $email): string
    {
        global $wpdb;
        $result = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT p.website_url
                 FROM {$wpdb->users} u
                 INNER JOIN {$wpdb->prefix}amai_business_profile p ON p.tenant_id = 'default'
                 WHERE u.user_email = %s
                 LIMIT 1",
                $email
            )
        );
        return is_string($result) ? $result : '';
    }
}