<?php
require_once __DIR__ . '/../app/Core.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/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();
$settings = new Setting();
$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');
        $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()));
            $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' => $provider === 'gmail' ? 'gmail-watch' : 'graph-subscription',
                'resource_scope' => 'messages',
                'subscription_id' => $subscriptionId,
                'expires_at' => $expiresAt,
                'verification_state' => 'verified',
                'metadata_json' => ['renewed_by_job' => true],
            ]);
            $queue->markDone((int)$job['id'], 'Mailbox subscription renewed.');
            $processed++;
            continue;
        }

        $mailboxes->updateSyncResult($mailboxId, [
            'sync_state' => 'syncing',
            'last_error' => null,
        ]);
        $cursorValue = $provider === 'gmail'
            ? 'history_' . $mailboxId . '_' . time()
            : 'delta_' . $mailboxId . '_' . time();
        $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,
        ];
        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');
        }
        $mailboxes->updateSyncResult($mailboxId, $update);
        $subscriptions->upsertForMailbox($mailboxId, [
            'provider' => $provider,
            'resource_name' => $provider === 'gmail' ? 'gmail-watch' : 'graph-subscription',
            'resource_scope' => 'messages',
            'subscription_id' => $subscriptionId,
            'expires_at' => $expiresAt,
            'verification_state' => 'verified',
            'metadata_json' => ['cursor' => $cursorValue, 'source' => 'sync_mailboxes.php'],
        ]);
        $queue->markDone((int)$job['id'], 'Mailbox sync completed.');
        $processed++;
    } catch (Throwable $e) {
        $mailboxes->updateSyncResult($mailboxId, [
            'sync_state' => 'error',
            'last_error' => $e->getMessage(),
        ]);
        $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;
