<?php

ob_start();
header('Content-Type: application/json; charset=utf-8');
set_time_limit(300);

function icylabForceSyncRespond($payload, $statusCode = 200)
{
    while (ob_get_level() > 0) {
        ob_end_clean();
    }

    http_response_code((int) $statusCode);
    echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

try {
    require_once __DIR__ . '/../../core/config.php';
    require_once __DIR__ . '/../../core/session.php';
    require_once __DIR__ . '/../../core/permissions.php';
    require_once __DIR__ . '/../../core/database.php';
    require_once __DIR__ . '/../../services/facto/FactoDocumentsSyncService.php';
    require_once __DIR__ . '/../../services/analytics/AnalyticsEngine.php';
    require_once __DIR__ . '/../../services/facto/ExportDocumentReconciliationService.php';
    require_once __DIR__ . '/../../core/notifications.php';

    require_login();
    require_permission('module.admin');
    if (strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET')) !== 'POST') {
        icylabForceSyncRespond(array('success' => false, 'message' => 'Método no permitido.'), 405);
    }
    csrf_require_valid_request();

    $pdo = db();
    $fromDate = date('Y-m-d', strtotime('-30 days'));
    $toDate = date('Y-m-d');
    $perPage = 100;

    // Sincroniza documentos emitidos. En FACTO: flag 1 = emitidos, flag 0 = recibidos.
    $documentSync = new FactoDocumentsSyncService();
    $documents = $documentSync->syncIssuedDocuments($fromDate, $toDate, $perPage);

    // Repara vínculos y tasas de exportaciones históricas ya almacenadas,
    // incluso cuando su fecha está fuera de la ventana de sincronización de 30 días.
    $exportReconciliation = (new ExportDocumentReconciliationService($pdo, 'production'))
        ->reconcileHistoricalExports(5000);

    $engine = new AnalyticsEngine();
    $engine->rebuild();

    // La sincronizacion FACTO solo importa y reconcilia documentos.
    // La creacion de oportunidades de reposicion se ejecuta en un job BI independiente.

    icylabForceSyncRespond(array(
        'success' => true,
        'message' => 'Sincronización completada.',
        'new_customers' => 0,
        'documents' => $documents,
        'export_reconciliation' => $exportReconciliation,
        'restock_opportunities_created' => 0,
        'restock_automation' => 'decoupled_daily_bi_job',
        'from' => $fromDate,
        'to' => $toDate
    ));
} catch (Throwable $e) {
    // Un fallo del subsistema de notificaciones nunca debe ocultar el error real del sync.
    if (function_exists('notify_admins_event')) {
        try {
            notify_admins_event('system.sync_error', array(
                'title' => 'Error en sincronización FACTO',
                'body' => 'El proceso manual de sincronización falló.' . "\nDetalle: " . $e->getMessage(),
                'url' => '/modules/dashboard/',
                'module' => 'system',
                'related_type' => 'sync',
                'related_id' => null,
                'priority' => 'critical',
                'critical' => true,
                'force_email' => true,
                'actor_user_id' => function_exists('notification_actor_user_id')
                    ? notification_actor_user_id()
                    : null,
                'dedupe_key' => 'system.sync_error:facto:' . date('YmdHi') . ':' . substr(md5($e->getMessage()), 0, 12)
            ));
        } catch (Throwable $notificationError) {
            error_log('ICYLAB notification failure during FACTO sync error handling: ' . $notificationError->getMessage());
        }
    }

    error_log('ICYLAB manual FACTO sync failed: ' . $e->getMessage());

    icylabForceSyncRespond(array(
        'success' => false,
        'message' => $e->getMessage()
    ), 500);
}
