<?php
require_once __DIR__ . '/../app/Core.php';
require_once __DIR__ . '/../app/services.php';
require_once __DIR__ . '/../app/models/QueueJob.php';
require_once __DIR__ . '/../app/models/ConnectedMailbox.php';
require_once __DIR__ . '/../app/models/MailboxWebhookSubscription.php';
require_once __DIR__ . '/../app/models/MailboxSyncEvent.php';
require_once __DIR__ . '/../app/models/Setting.php';

if (!app_config_exists()) {
    fwrite(STDERR, "Config missing. Run install first.\n");
    exit(1);
}

start_session();
date_default_timezone_set(config('app.timezone', 'America/Chicago'));

$queue = new QueueJob();
$mailboxes = new ConnectedMailbox();
$subscriptions = new MailboxWebhookSubscription();
$syncEvents = new MailboxSyncEvent();
$settings = new Setting();
$emailService = new EmailService();
$processed = 0;

while (true) {
    $job = null;
    foreach (['mailbox_subscription_renew', 'mailbox_sync'] as $type) {
        $candidate = $queue->nextRunnable($type);
        if ($candidate) {
            $job = $candidate;
            break;
        }
    }
    if (!$job) {
        break;
    }

    $queue->markProcessing((int)$job['id']);
    $payload = json_decode((string)($job['payload_json'] ?? ''), true) ?: [];
    $mailboxId = (int)($payload['connected_mailbox_id'] ?? 0);
    $mailbox = $mailboxes->find($mailboxId);
    if (!$mailbox) {
        $queue->markFailed((int)$job['id'], 'Connected mailbox not found.');
        continue;
    }

    try {
        $provider = (string)($mailbox['provider'] ?? 'gmail');
        $syncMode = (string)($mailbox['sync_mode'] ?? 'imap_bridge');
        $now = new DateTimeImmutable('now');
        $expiresAt = $provider === 'gmail'
            ? $now->modify('+6 days 23 hours')->format('Y-m-d H:i:s')
            : $now->modify('+3 days')->format('Y-m-d H:i:s');

        if ((string)$job['job_type'] === 'mailbox_subscription_renew') {
            $subscriptionId = (string)($mailbox['subscription_id'] ?: ($provider . '-sub-' . $mailboxId . '-' . time()));
            $note = $syncMode === 'imap_bridge'
                ? 'IMAP bridge verified. No provider webhook renewal required.'
                : 'Mailbox subscription renewed.';
            $mailboxes->updateSyncResult($mailboxId, [
                'subscription_id' => $subscriptionId,
                'subscription_expires_at' => $expiresAt,
                'oauth_status' => ($mailbox['oauth_status'] ?? 'planned') === 'planned' ? 'connected' : (string)($mailbox['oauth_status'] ?? 'connected'),
                'sync_state' => 'idle',
                'last_error' => null,
            ]);
            $subscriptions->upsertForMailbox($mailboxId, [
                'provider' => $provider,
                'resource_name' => $syncMode === 'imap_bridge' ? 'imap-poll' : ($provider === 'gmail' ? 'gmail-watch' : 'graph-subscription'),
                'resource_scope' => 'messages',
                'subscription_id' => $subscriptionId,
                'expires_at' => $expiresAt,
                'verification_state' => 'verified',
                'metadata_json' => ['renewed_by_job' => true, 'sync_mode' => $syncMode],
            ]);
            $syncEvents->log([
                'connected_mailbox_id' => $mailboxId,
                'event_type' => 'renewal',
                'status' => 'ok',
                'summary' => $note,
                'detail_json' => ['job_id' => (int)$job['id'], 'subscription_id' => $subscriptionId],
                'sync_mode' => $syncMode,
                'provider' => $provider,
            ]);
            $queue->markDone((int)$job['id'], $note);
            $processed++;
            continue;
        }

        $mailboxes->updateSyncResult($mailboxId, [
            'sync_state' => 'syncing',
            'last_error' => null,
        ]);

        $subscriptionId = (string)($mailbox['subscription_id'] ?: ($provider . '-sub-' . $mailboxId . '-' . time()));
        $update = [
            'oauth_status' => ($mailbox['oauth_status'] ?? 'planned') === 'planned' ? 'connected' : (string)($mailbox['oauth_status'] ?? 'connected'),
            'sync_state' => 'idle',
            'last_synced_at' => $now->format('Y-m-d H:i:s'),
            'subscription_id' => $subscriptionId,
            'subscription_expires_at' => $expiresAt,
            'last_error' => null,
        ];
        $summaryBits = [];
        $result = ['imported' => 0, 'highest_uid' => (int)($mailbox['last_message_uid'] ?? 0)];

        if ($syncMode === 'imap_bridge') {
            $result = $emailService->syncConnectedMailbox($mailbox);
            $update['last_message_uid'] = (int)($result['highest_uid'] ?? ($mailbox['last_message_uid'] ?? 0));
            $update['imported_message_count'] = (int)($mailbox['imported_message_count'] ?? 0) + (int)($result['imported'] ?? 0);
            $update['last_imported_at'] = $now->format('Y-m-d H:i:s');
            $summaryBits[] = 'Imported ' . (int)($result['imported'] ?? 0) . ' new emails';
            $summaryBits[] = 'highest UID ' . (int)($result['highest_uid'] ?? 0);
        } else {
            $cursorValue = $provider === 'gmail'
                ? 'history_' . $mailboxId . '_' . time()
                : 'delta_' . $mailboxId . '_' . time();
            if ($provider === 'gmail') {
                $update['history_cursor'] = $cursorValue;
                $update['watch_topic'] = (string)($mailbox['watch_topic'] ?: 'projects/your-project/topics/gmail-mail-sync');
            } else {
                $update['delta_link'] = $cursorValue;
                $update['webhook_endpoint'] = (string)($mailbox['webhook_endpoint'] ?: 'https://your-app.example.com/index.php?route=webhook/mailbox');
            }
            $summaryBits[] = 'Foundation sync refreshed';
        }

        $summary = implode(' • ', $summaryBits);
        $mailboxes->updateSyncResult($mailboxId, $update);
        $subscriptions->upsertForMailbox($mailboxId, [
            'provider' => $provider,
            'resource_name' => $syncMode === 'imap_bridge' ? 'imap-poll' : ($provider === 'gmail' ? 'gmail-watch' : 'graph-subscription'),
            'resource_scope' => 'messages',
            'subscription_id' => $subscriptionId,
            'expires_at' => $expiresAt,
            'verification_state' => 'verified',
            'metadata_json' => ['source' => 'sync_mailboxes.php', 'sync_mode' => $syncMode],
        ]);
        $syncEvents->log([
            'connected_mailbox_id' => $mailboxId,
            'event_type' => 'sync',
            'status' => 'ok',
            'summary' => $summary,
            'detail_json' => ['job_id' => (int)$job['id']],
            'imported_count' => (int)($result['imported'] ?? 0),
            'highest_uid' => (int)($result['highest_uid'] ?? 0),
            'sync_mode' => $syncMode,
            'provider' => $provider,
        ]);
        $queue->markDone((int)$job['id'], $summary);
        $processed++;
    } catch (Throwable $e) {
        $mailboxes->updateSyncResult($mailboxId, [
            'sync_state' => 'error',
            'last_error' => $e->getMessage(),
        ]);
        $syncEvents->log([
            'connected_mailbox_id' => $mailboxId,
            'event_type' => (string)($job['job_type'] ?? 'sync') === 'mailbox_subscription_renew' ? 'renewal' : 'sync',
            'status' => 'failed',
            'summary' => $e->getMessage(),
            'detail_json' => ['job_id' => (int)$job['id']],
            'sync_mode' => (string)($mailbox['sync_mode'] ?? 'imap_bridge'),
            'provider' => (string)($mailbox['provider'] ?? 'gmail'),
        ]);
        $queue->markFailed((int)$job['id'], $e->getMessage());
    }
}

$settings->set('mailbox_sync_last_heartbeat', date('Y-m-d H:i:s'));
echo 'Processed mailbox jobs: ' . $processed . PHP_EOL;
