<?php
/**
 * ICEBERG Cloud Sync - Receptor de datos desde Edge Server
 * Subir a: icebergecuador.com/Cuenca/Plan/api/sync.php
 *
 * Recibe ventas/sesiones del servidor local y las guarda en MySQL.
 * El Edge Server envia lotes cada 60 segundos.
 */

// --- CONFIGURACION (cambiar segun tu cPanel) ---
$DB_HOST = 'localhost';
$DB_NAME = 'icerbger_cloud';
$DB_USER = 'icerbger_Dathor';
$DB_PASS = 'Quince0Tres';
$SYNC_KEY = 'iceberg-sync-2026'; // debe coincidir con config.py
// ------------------------------------------------

header('Content-Type: application/json');

// Solo aceptar POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['status' => 'error', 'message' => 'Solo POST']);
    exit;
}

// Leer body
$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
    http_response_code(400);
    echo json_encode(['status' => 'error', 'message' => 'JSON invalido']);
    exit;
}

// Validar clave
if (($input['key'] ?? '') !== $SYNC_KEY) {
    http_response_code(403);
    echo json_encode(['status' => 'error', 'message' => 'Clave invalida']);
    exit;
}

$venue_id = $input['venue_id'] ?? 'unknown';
$records = $input['records'] ?? [];

if (empty($records)) {
    echo json_encode(['status' => 'ok', 'synced_ids' => [], 'message' => 'Sin registros']);
    exit;
}

// Conectar a MySQL
try {
    $pdo = new PDO("mysql:host=$DB_HOST;dbname=$DB_NAME;charset=utf8mb4", $DB_USER, $DB_PASS);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => 'Error de DB: ' . $e->getMessage()]);
    exit;
}

// Crear tabla si no existe
$pdo->exec("
    CREATE TABLE IF NOT EXISTS sync_records (
        id INT AUTO_INCREMENT PRIMARY KEY,
        venue_id VARCHAR(50) NOT NULL,
        local_id INT NOT NULL,
        table_name VARCHAR(50) NOT NULL,
        record_id VARCHAR(50) NOT NULL,
        action VARCHAR(20) NOT NULL,
        payload JSON,
        local_created_at DATETIME,
        synced_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        UNIQUE KEY unique_record (venue_id, table_name, record_id, action)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
");

// Crear tabla de sesiones para reportes faciles
$pdo->exec("
    CREATE TABLE IF NOT EXISTS sessions_cloud (
        id VARCHAR(50) PRIMARY KEY,
        venue_id VARCHAR(50) NOT NULL,
        package_id VARCHAR(50),
        amount DECIMAL(10,2),
        payment_method VARCHAR(20),
        programmed_at DATETIME,
        synced_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        INDEX idx_venue (venue_id),
        INDEX idx_date (programmed_at)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
");

$synced_ids = [];
$errors = 0;

$stmt = $pdo->prepare("
    INSERT IGNORE INTO sync_records
    (venue_id, local_id, table_name, record_id, action, payload, local_created_at)
    VALUES (?, ?, ?, ?, ?, ?, ?)
");

$stmt_session = $pdo->prepare("
    INSERT IGNORE INTO sessions_cloud
    (id, venue_id, package_id, amount, payment_method, programmed_at)
    VALUES (?, ?, ?, ?, ?, ?)
");

foreach ($records as $record) {
    try {
        $stmt->execute([
            $venue_id,
            $record['id'],
            $record['table_name'],
            $record['record_id'],
            $record['action'],
            $record['payload'],
            $record['created_at'],
        ]);

        // Si es una sesion, insertarla tambien en sessions_cloud
        if ($record['table_name'] === 'sessions' && $record['action'] === 'insert') {
            $payload = json_decode($record['payload'], true);
            if ($payload) {
                try {
                    // Migrar: agregar columnas si no existen
                    foreach (['agent_id VARCHAR(50) DEFAULT NULL', 'cashier VARCHAR(50) DEFAULT \'default\'', 'package_name VARCHAR(100) DEFAULT NULL', 'status VARCHAR(20) DEFAULT \'active\'', 'folio_number VARCHAR(30) DEFAULT NULL'] as $_col) {
                        try { $pdo->exec("ALTER TABLE sessions_cloud ADD COLUMN $_col"); } catch (Exception $e) {}
                    }

                    $pdo->prepare("
                        INSERT INTO sessions_cloud (id, venue_id, package_id, package_name, amount, status, payment_method, cashier, agent_id, programmed_at, folio_number)
                        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                        ON DUPLICATE KEY UPDATE amount=VALUES(amount), status=VALUES(status), cashier=VALUES(cashier), agent_id=VALUES(agent_id), folio_number=VALUES(folio_number)
                    ")->execute([
                        $payload['id'] ?? $record['record_id'],
                        $venue_id,
                        $payload['package_id'] ?? null,
                        $payload['package_name'] ?? null,
                        $payload['amount'] ?? 0,
                        $payload['status'] ?? 'active',
                        $payload['payment_method'] ?? 'cash',
                        $payload['cashier'] ?? 'default',
                        $payload['agent_id'] ?? null,
                        $payload['programmed_at'] ?? null,
                        $payload['folio_number'] ?? null,
                    ]);
                } catch (Exception $e) { /* columnas nuevas pueden no existir aun */ }
            }
        }

        // Si es un agente, upsert o delete en agents_cloud
        if ($record['table_name'] === 'agents') {
            $payload = json_decode($record['payload'], true);
            if ($payload) {
                try {
                    $pdo->prepare("
                        CREATE TABLE IF NOT EXISTS agents_cloud (
                            id VARCHAR(50) NOT NULL, venue_id VARCHAR(50) NOT NULL, name VARCHAR(100) NOT NULL,
                            status VARCHAR(20) DEFAULT 'offline', last_heartbeat DATETIME DEFAULT NULL,
                            synced_at DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (venue_id, id)
                        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
                    ")->execute();

                    if ($record['action'] === 'delete') {
                        // Eliminar agente del cloud
                        $pdo->prepare("DELETE FROM agents_cloud WHERE id = ? AND venue_id = ?")
                            ->execute([$payload['id'], $venue_id]);
                    } else {
                        $pdo->prepare("
                            INSERT INTO agents_cloud (id, venue_id, name, status, last_heartbeat, synced_at)
                            VALUES (?, ?, ?, ?, ?, NOW())
                            ON DUPLICATE KEY UPDATE name=VALUES(name), status=VALUES(status), last_heartbeat=VALUES(last_heartbeat), synced_at=NOW()
                        ")->execute([
                            $payload['id'], $venue_id, $payload['name'] ?? '',
                            $payload['status'] ?? 'offline', $payload['last_heartbeat'] ?? null,
                        ]);

                        // Auto-crear terminal en terminals_cloud si no existe
                        // Para que el Operator pueda adoptar combos inmediatamente
                        try {
                            $pdo->exec("CREATE TABLE IF NOT EXISTS terminals_cloud (
                                id VARCHAR(50) NOT NULL, venue_id VARCHAR(50) NOT NULL,
                                name VARCHAR(100) DEFAULT '', price DECIMAL(10,2) NOT NULL DEFAULT 0,
                                created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                                PRIMARY KEY (venue_id, id)
                            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
                            $pdo->prepare("
                                INSERT IGNORE INTO terminals_cloud (id, venue_id, name, price)
                                VALUES (?, ?, ?, 0)
                            ")->execute([
                                $payload['id'], $venue_id, $payload['name'] ?? 'Caja',
                            ]);
                        } catch (Exception $e) { /* ignore */ }
                    }
                } catch (Exception $e) { /* ignore */ }
            }
        }

        // Si es un paquete, upsert en packages_cloud
        if ($record['table_name'] === 'packages') {
            $payload = json_decode($record['payload'], true);
            if ($payload) {
                try {
                    $pdo->prepare("
                        CREATE TABLE IF NOT EXISTS packages_cloud (
                            id VARCHAR(50) NOT NULL, venue_id VARCHAR(50) NOT NULL, name VARCHAR(100) NOT NULL,
                            minutes INT NOT NULL, price DECIMAL(10,2) NOT NULL, color VARCHAR(20) DEFAULT 'all',
                            active TINYINT DEFAULT 1, synced_at DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (venue_id, id)
                        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
                    ")->execute();
                    $pdo->prepare("
                        INSERT INTO packages_cloud (id, venue_id, name, minutes, price, color, active, synced_at)
                        VALUES (?, ?, ?, ?, ?, ?, ?, NOW())
                        ON DUPLICATE KEY UPDATE name=VALUES(name), minutes=VALUES(minutes), price=VALUES(price),
                                                color=VALUES(color), active=VALUES(active), synced_at=NOW()
                    ")->execute([
                        $payload['id'], $venue_id, $payload['name'] ?? '',
                        $payload['minutes'] ?? 0, $payload['price'] ?? 0,
                        $payload['color'] ?? 'all', $payload['active'] ?? 1,
                    ]);
                } catch (Exception $e) { /* ignore */ }
            }
        }

        // Si es un terminal_package (combo assign/unassign desde POS local), sync al cloud
        if ($record['table_name'] === 'terminal_packages') {
            $payload = json_decode($record['payload'], true);
            if ($payload) {
                try {
                    // Crear tabla si no existe
                    $pdo->exec("CREATE TABLE IF NOT EXISTS terminal_packages_cloud (
                        id INT AUTO_INCREMENT PRIMARY KEY, venue_id VARCHAR(50) NOT NULL,
                        agent_id VARCHAR(50) NOT NULL, combo_id VARCHAR(50) NOT NULL,
                        name VARCHAR(100) DEFAULT '', price DECIMAL(10,2) DEFAULT 0,
                        active TINYINT DEFAULT 1, synced_at DATETIME DEFAULT CURRENT_TIMESTAMP,
                        UNIQUE KEY uq_venue_agent_combo (venue_id, agent_id, combo_id)
                    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

                    $agent_id = $payload['agent_id'] ?? '';
                    $combo_id = $payload['combo_id'] ?? '';

                    if ($record['action'] === 'combo_assign') {
                        $pdo->prepare("
                            INSERT INTO terminal_packages_cloud (venue_id, agent_id, combo_id, name, price, active, synced_at)
                            VALUES (?, ?, ?, ?, ?, 1, NOW())
                            ON DUPLICATE KEY UPDATE name=VALUES(name), price=VALUES(price), active=1, synced_at=NOW()
                        ")->execute([
                            $venue_id, $agent_id, $combo_id,
                            $payload['name'] ?? '', $payload['price'] ?? 0,
                        ]);
                    } elseif ($record['action'] === 'combo_unassign') {
                        $pdo->prepare("
                            UPDATE terminal_packages_cloud SET active = 0, synced_at = NOW()
                            WHERE venue_id = ? AND agent_id = ? AND combo_id = ?
                        ")->execute([$venue_id, $agent_id, $combo_id]);
                    }

                    // Auto-migracion: agregar source_venue a package_changes
                    try {
                        $pdo->exec("ALTER TABLE package_changes ADD COLUMN source_venue VARCHAR(50) DEFAULT NULL");
                    } catch (Exception $e) { /* ya existe */ }

                    // Crear package_changes con source_venue para evitar loops
                    $pdo->prepare("
                        INSERT INTO package_changes (venue_id, package_id, action, payload, source_venue)
                        VALUES (?, ?, ?, ?, ?)
                    ")->execute([
                        $venue_id, $combo_id, $record['action'],
                        json_encode($payload), $venue_id,
                    ]);
                } catch (Exception $e) { /* ignore */ }
            }
        }

        // Si es un combo_registry, upsert o delete en combo_registry_cloud
        if ($record['table_name'] === 'combo_registry') {
            $payload = json_decode($record['payload'], true);
            if ($payload) {
                try {
                    $pdo->prepare("
                        CREATE TABLE IF NOT EXISTS combo_registry_cloud (
                            combo_id VARCHAR(50) NOT NULL, venue_id VARCHAR(50) NOT NULL, agent_id VARCHAR(50) NOT NULL,
                            config_json TEXT DEFAULT NULL,
                            synced_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uq_venue_combo (venue_id, combo_id)
                        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
                    ")->execute();

                    // Migracion: agregar config_json si no existe
                    try {
                        $pdo->exec("ALTER TABLE combo_registry_cloud ADD COLUMN config_json TEXT DEFAULT NULL");
                    } catch (Exception $e) { /* columna ya existe */ }

                    if ($record['action'] === 'delete') {
                        // Eliminar combo y sus asignaciones del cloud
                        $combo_id = $payload['combo_id'] ?? $record['record_id'];
                        $pdo->prepare("DELETE FROM combo_registry_cloud WHERE combo_id = ? AND venue_id = ?")
                            ->execute([$combo_id, $venue_id]);
                        $pdo->prepare("DELETE FROM terminal_packages_cloud WHERE combo_id = ? AND venue_id = ?")
                            ->execute([$combo_id, $venue_id]);
                    } else {
                        $config_json = $payload['config_json'] ?? null;
                        $pdo->prepare("
                            INSERT INTO combo_registry_cloud (combo_id, venue_id, agent_id, config_json, synced_at)
                            VALUES (?, ?, ?, ?, NOW())
                            ON DUPLICATE KEY UPDATE agent_id=VALUES(agent_id), config_json=VALUES(config_json), synced_at=NOW()
                        ")->execute([
                            $payload['combo_id'] ?? $record['record_id'], $venue_id,
                            $payload['agent_id'] ?? '', $config_json,
                        ]);
                    }
                } catch (Exception $e) { /* ignore */ }
            }
        }

        $synced_ids[] = $record['id'];
    } catch (Exception $e) {
        $errors++;
    }
}

// Notificar cambios al SSE tracker
if (!empty($synced_ids)) {
    try {
        $pdo->exec("CREATE TABLE IF NOT EXISTS change_tracker (
            entity VARCHAR(50) PRIMARY KEY,
            last_changed DATETIME DEFAULT CURRENT_TIMESTAMP
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

        // Detectar que entidades cambiaron
        $changed = [];
        foreach ($records as $r) {
            $t = $r['table_name'] ?? '';
            if ($t === 'sessions') $changed['ventas'] = true;
            if ($t === 'agents') $changed['agentes'] = true;
            if ($t === 'packages') $changed['paquetes'] = true;
            if ($t === 'combo_registry') $changed['combos'] = true;
            if ($t === 'terminal_packages') $changed['terminales'] = true;
        }
        $changed['dashboard'] = true; // siempre actualizar dashboard

        foreach (array_keys($changed) as $entity) {
            $pdo->prepare("INSERT INTO change_tracker (entity, last_changed) VALUES (?, NOW())
                ON DUPLICATE KEY UPDATE last_changed = NOW()")->execute([$entity]);
        }
    } catch (Exception $e) { /* ignore */ }
}

echo json_encode([
    'status' => 'ok',
    'synced_ids' => $synced_ids,
    'received' => count($records),
    'synced' => count($synced_ids),
    'errors' => $errors,
]);
