<?php

require_once __DIR__ . '/../core/cron_guard.php';
icylab_require_cron_access();

require_once __DIR__ . '/../core/config.php';
require_once __DIR__ . '/../core/database.php';
require_once __DIR__ . '/../services/crm/PaymentStatusService.php';
require_once __DIR__ . '/../services/crm/OpportunityLifecycleService.php';
require_once __DIR__ . '/../services/crm/RestockForecastService.php';
require_once __DIR__ . '/../services/notifications/NotificationService.php';
require_once __DIR__ . '/../services/finance/ExchangeRateService.php';
require_once __DIR__ . '/../services/facto/ExportDocumentReconciliationService.php';
require_once __DIR__ . '/../services/analytics/AnalyticsEngine.php';

if (PHP_SAPI !== 'cli') header('Content-Type: text/plain; charset=utf-8');

$pdo = db();
$updatedOverdue = 0;
$dueActions = 0;
$notificationResult = array('processed' => 0, 'sent' => 0, 'failed' => 0);
$mvpResult = array('processed' => 0, 'high_value_stalled' => 0, 'quote_no_tax_document' => 0, 'billing_due_today' => 0, 'billing_overdue_critical' => 0);
$archiveResult = array('eligible' => 0, 'archived' => 0, 'skipped_invalid_dte' => 0, 'cutoff' => date('Y-m-01'));
$restockResult = array('customers_evaluated' => 0, 'forecasts_refreshed' => 0, 'forecasts_skipped' => 0, 'forecast_refresh_errors' => 0, 'customer_lifecycle_updated' => 0, 'purchases_reconciled' => 0, 'forecasts_converted' => 0, 'stale_opportunities_closed' => 0);
$fxDailyResult = array('resolved' => 0, 'missing' => 0, 'items' => array());
$fxBackfillResult = array('evaluated' => 0, 'resolved' => 0, 'missing' => 0, 'errors' => 0);
$exportReconciliation = array('documents_total' => 0, 'documents_linked_after' => 0, 'documents_unlinked' => 0, 'fx_resolved' => 0, 'fx_missing' => 0, 'fx_errors' => 0);
$analyticsRebuilt = false;
$errors = array();

try {
    $exportReconciliation = (new ExportDocumentReconciliationService($pdo, 'production'))->reconcileHistoricalExports(5000);
    $exchangeRates = new ExchangeRateService($pdo);
    $fxDailyResult = $exchangeRates->syncDailyRates(date('Y-m-d'));
    $fxBackfillResult = $exchangeRates->backfillDocuments(500, false);
    if (($fxBackfillResult['resolved'] ?? 0) > 0) {
        (new AnalyticsEngine($pdo))->rebuild();
        $analyticsRebuilt = true;
    }
} catch (Throwable $e) {
    $errors[] = 'tipos de cambio: ' . $e->getMessage();
    error_log('daily_jobs exchange rate error: ' . $e->getMessage());
}

try {
    $updatedOverdue = PaymentStatusService::processOverdueOpportunities($pdo);
} catch (Throwable $e) {
    $errors[] = 'cobranza: ' . $e->getMessage();
    error_log('daily_jobs overdue error: ' . $e->getMessage());
}

try {
    $lifecycle = new OpportunityLifecycleService($pdo);
    $archiveResult = $lifecycle->archiveEligibleInvoiced('month_end');
} catch (Throwable $e) {
    $errors[] = 'archivo mensual: ' . $e->getMessage();
    error_log('daily_jobs archive error: ' . $e->getMessage());
}


try {
    $restockService = new RestockForecastService($pdo);
    $restockResult = $restockService->processDaily();
} catch (Throwable $e) {
    $errors[] = 'reposicion predictiva: ' . $e->getMessage();
    error_log('daily_jobs restock error: ' . $e->getMessage());
}

try {
    $notificationService = new NotificationService($pdo);
    $dueActions = $notificationService->processDueActionNotifications(1);
    $mvpResult = $notificationService->processExecutiveMvpNotifications();
    $notificationResult = $notificationService->processEmailQueue(50);
} catch (Throwable $e) {
    $errors[] = 'notificaciones: ' . $e->getMessage();
    error_log('daily_jobs notifications error: ' . $e->getMessage());
}

if (!$analyticsRebuilt) {
    try {
        (new AnalyticsEngine($pdo))->rebuild();
        $analyticsRebuilt = true;
    } catch (Throwable $e) {
        $errors[] = 'analytics: ' . $e->getMessage();
        error_log('daily_jobs analytics error: ' . $e->getMessage());
    }
}

if ($errors && PHP_SAPI !== 'cli') http_response_code(500);

echo $errors ? 'daily_jobs COMPLETED_WITH_ERRORS' . PHP_EOL : 'daily_jobs OK' . PHP_EOL;
echo 'Exportaciones vinculadas: ' . (int)($exportReconciliation['documents_linked_after'] ?? 0) . PHP_EOL;
echo 'Exportaciones sin vincular: ' . (int)($exportReconciliation['documents_unlinked'] ?? 0) . PHP_EOL;
echo 'Exportaciones con FX resuelto: ' . (int)($exportReconciliation['fx_resolved'] ?? 0) . PHP_EOL;
echo 'Tasas diarias resueltas: ' . (int)($fxDailyResult['resolved'] ?? 0) . PHP_EOL;
echo 'Documentos FX evaluados: ' . (int)($fxBackfillResult['evaluated'] ?? 0) . PHP_EOL;
echo 'Documentos FX normalizados: ' . (int)($fxBackfillResult['resolved'] ?? 0) . PHP_EOL;
echo 'Documentos FX pendientes: ' . (int)($fxBackfillResult['missing'] ?? 0) . PHP_EOL;
echo 'Analytics reconstruido: ' . ($analyticsRebuilt ? 'si' : 'no') . PHP_EOL;
echo 'Oportunidades marcadas como atrasadas: ' . (int)$updatedOverdue . PHP_EOL;
echo 'Facturadas elegibles para archivo: ' . (int)($archiveResult['eligible'] ?? 0) . PHP_EOL;
echo 'Facturadas archivadas: ' . (int)($archiveResult['archived'] ?? 0) . PHP_EOL;
echo 'Facturadas omitidas por DTE invalido: ' . (int)($archiveResult['skipped_invalid_dte'] ?? 0) . PHP_EOL;
echo 'Clientes recientes evaluados para reposicion: ' . (int)($restockResult['customers_evaluated'] ?? 0) . PHP_EOL;
echo 'Pronosticos creados o actualizados: ' . (int)($restockResult['forecasts_refreshed'] ?? 0) . PHP_EOL;
echo 'Clientes omitidos por reglas de reposicion: ' . (int)($restockResult['forecasts_skipped'] ?? 0) . PHP_EOL;
echo 'Errores al actualizar pronosticos: ' . (int)($restockResult['forecast_refresh_errors'] ?? 0) . PHP_EOL;
echo 'Clientes reclasificados por ciclo: ' . (int)($restockResult['customer_lifecycle_updated'] ?? 0) . PHP_EOL;
echo 'Reposiciones confirmadas por compra: ' . (int)($restockResult['purchases_reconciled'] ?? 0) . PHP_EOL;
echo 'Pronosticos convertidos en oportunidades: ' . (int)($restockResult['forecasts_converted'] ?? 0) . PHP_EOL;
echo 'Reposiciones vencidas cerradas: ' . (int)($restockResult['stale_opportunities_closed'] ?? 0) . PHP_EOL;
echo 'Recordatorios de proxima accion generados: ' . (int)$dueActions . PHP_EOL;
echo 'Alertas MVP ejecutivas generadas: ' . (int)($mvpResult['processed'] ?? 0) . PHP_EOL;
echo 'Emails procesados: ' . (int)($notificationResult['processed'] ?? 0) . PHP_EOL;
echo 'Emails enviados: ' . (int)($notificationResult['sent'] ?? 0) . PHP_EOL;
echo 'Emails fallidos: ' . (int)($notificationResult['failed'] ?? 0) . PHP_EOL;
if ($errors) echo 'Errores: ' . implode(' | ', $errors) . PHP_EOL;
