<br />
<b>Warning</b>:  Undefined variable $auth in <b>/home/pevo0181/public_html/pia-soft.com/cleania/routes/index.php</b> on line <b>542</b><br />
<br />
<b>Warning</b>:  Trying to access array offset on value of type null in <b>/home/pevo0181/public_html/pia-soft.com/cleania/routes/index.php</b> on line <b>542</b><br />
<?php
// ============================================================
//  PIASCHOOL SYNC API — sync.php
//  Deposer dans : https://pia-soft.com/piaschool/piaschool1/
// ============================================================
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}

// ── Configuration base de données o2switch
define('DB_HOST', 'localhost');
define('DB_NAME', 'pevo0181_piaschool1');
define('DB_USER', 'pevo0181_piaschool1');
define('DB_PASS', 'Piasoft2021');

// ── Tokens acceptés (ancien et nouveau)
$ACCEPTED_TOKENS = [
    'PIASCHOOL_SYNC_TOKEN_2026_SECRET',  // nouveau token
    'Pia2026xK9mZqR7vLSnW4'              // ancien token
];

// ── Connexion
try {
    $pdo = new PDO(
        "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4",
        DB_USER, DB_PASS,
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
    );
} catch (Exception $e) {
    http_response_code(500);
    echo json_encode(['success' => false, 'message' => 'DB Error: ' . $e->getMessage()]);
    exit();
}

// ── Vérifier le token (header ou GET)
$token = $_SERVER['HTTP_AUTHORIZATION'] ?? $_GET['token'] ?? '';
$token = str_replace('Bearer ', '', trim($token));

global $ACCEPTED_TOKENS;
if (!in_array($token, $ACCEPTED_TOKENS)) {
    http_response_code(401);
    echo json_encode(['success' => false, 'message' => 'Token invalide: ' . $token]);
    exit();
}

// ── Router les actions
$action = $_GET['action'] ?? 'sync';
$body   = json_decode(file_get_contents('php://input'), true) ?? [];

switch ($action) {
    case 'sync':         handleSync($pdo, $body);         break;
    case 'ping':         handlePing($pdo);                break;
    case 'status':       handleStatus($pdo);              break;
    case 'upload_photo':        handleUploadPhoto($pdo);           break;
    case 'upload_photos_batch': handleUploadPhotosBatch($pdo, $body); break;
    case 'debug_path':          handleDebugPath();                     break;
    default:
        http_response_code(400);
        echo json_encode(['success' => false, 'message' => 'Action inconnue: ' . $action]);
}

// ══════════════════════════════════════════════════
//  SYNC : Recevoir et insérer les données
// ══════════════════════════════════════════════════
function handleSync($pdo, $data) {
    $results = [];
    $tables  = $data['tables'] ?? [];

    if (empty($tables)) {
        echo json_encode(['success' => false, 'message' => 'Aucune donnee recue']);
        return;
    }

    foreach ($tables as $tableName => $records) {
        if (empty($records)) continue;
        try {
            $count = upsertRecords($pdo, $tableName, $records);
            $results[$tableName] = ['synced' => $count, 'status' => 'ok'];
            logSync($pdo, $tableName, $count, 'ok');
        } catch (Exception $e) {
            $results[$tableName] = [
                'synced'  => 0,
                'status'  => 'error',
                'message' => $e->getMessage()
            ];
            logSync($pdo, $tableName, 0, 'error', $e->getMessage());
        }
    }

    echo json_encode([
        'success'   => true,
        'synced_at' => date('Y-m-d H:i:s'),
        'results'   => $results
    ]);
}

// ── Tables autorisées à synchroniser
function getAllowedTables() {
    return [
        'eleves',
        'classes',
        'niveaux',
        'sections',
        'annees_scolaires',
        'inscriptions',
        'matieres',
        'notes',
        'sessions_evaluation',
        'presences',
        'arrivee_ecole_eleve',
        'pension_paiements',
        'pension_config',
        'pension_tranches',
        'kit_articles',
        'kit_eleve',
        'notifications',
        'push_diffusions',
        'config_systeme'
    ];
}

// ── Insérer ou mettre à jour des enregistrements
function upsertRecords($pdo, $table, $records) {
    if (!in_array($table, getAllowedTables())) {
        throw new Exception("Table non autorisee : $table");
    }

    // Verifier que la table existe
    $check = $pdo->query("SHOW TABLES LIKE '$table'");
    if ($check->rowCount() === 0) {
        throw new Exception("Table inexistante en base distante : $table");
    }

    $count = 0;
    foreach ($records as $record) {
        if (empty($record)) continue;

        // Ajouter synced_at
        $record['synced_at'] = date('Y-m-d H:i:s');

        // Filtrer les colonnes qui existent vraiment dans la table
        $colsExist = getTableColumns($pdo, $table);
        $record    = array_intersect_key($record, array_flip($colsExist));

        if (empty($record)) continue;

        $cols    = array_keys($record);
        $vals    = array_values($record);
        $colList = implode(', ', array_map(fn($c) => "`$c`", $cols));
        $phList  = implode(', ', array_fill(0, count($cols), '?'));
        $updates = implode(', ', array_map(fn($c) => "`$c`=VALUES(`$c`)", $cols));

        $sql  = "INSERT INTO `$table` ($colList) VALUES ($phList) ON DUPLICATE KEY UPDATE $updates";
        $stmt = $pdo->prepare($sql);
        $stmt->execute($vals);
        $count++;
    }
    return $count;
}

// ── Cache des colonnes par table
$columnsCache = [];
function getTableColumns($pdo, $table) {
    global $columnsCache;
    if (isset($columnsCache[$table])) return $columnsCache[$table];
    $stmt = $pdo->query("SHOW COLUMNS FROM `$table`");
    $cols = array_column($stmt->fetchAll(PDO::FETCH_ASSOC), 'Field');
    $columnsCache[$table] = $cols;
    return $cols;
}

// ── Upload photo unique
function handleUploadPhoto($pdo) {
    // Verifier qu'on a bien un fichier
    if (empty($_FILES['photo'])) {
        echo json_encode(['success' => false, 'message' => 'Aucun fichier recu']);
        return;
    }
    $matricule = $_POST['matricule'] ?? '';
    $eleveId   = $_POST['eleve_id']  ?? '';
    $ext       = strtolower(pathinfo($_FILES['photo']['name'], PATHINFO_EXTENSION));
    if (!in_array($ext, ['jpg','jpeg','png'])) {
        echo json_encode(['success' => false, 'message' => 'Format non supporte']);
        return;
    }
    // Dossier destination
    // __DIR__ = .../piaschool/piaschool1/ donc remonter pour photos_eleves
    $dir = __DIR__ . '/../photos_eleves/';
    if (!is_dir($dir)) mkdir($dir, 0755, true);

    // Utiliser le vrai nom si fourni
    $filename = $_POST['filename'] ?? '';
    if (empty($filename)) {
        $filename = ($matricule ?: 'eleve_' . $eleveId) . '.' . $ext;
    }
    $dest = $dir . $filename;

    if (move_uploaded_file($_FILES['photo']['tmp_name'], $dest)) {
        // Mettre a jour la BD en ligne
        if ($eleveId) {
            try {
                $stmt = $pdo->prepare("UPDATE eleves SET photo = ? WHERE id = ?");
                $stmt->execute([$filename, $eleveId]);
            } catch (Exception $e) {}
        }
        echo json_encode(['success' => true, 'filename' => $filename]);
    } else {
        echo json_encode(['success' => false, 'message' => 'Erreur upload fichier']);
    }
}

// ── Upload photos en batch (base64)
function handleUploadPhotosBatch($pdo, $data) {
    $photos  = $data['photos'] ?? [];
    $results = [];
    // __DIR__ = .../piaschool/piaschool1/ donc remonter pour photos_eleves
    $dir = __DIR__ . '/../photos_eleves/';
    if (!is_dir($dir)) mkdir($dir, 0755, true);

    // Log pour debug
    error_log('Upload photos batch - dir: ' . $dir . ' - nb photos: ' . count($photos));

    foreach ($photos as $photo) {
        $eleveId   = $photo['eleve_id']  ?? '';
        $matricule = $photo['matricule'] ?? '';
        $ext       = strtolower($photo['extension'] ?? 'jpg');
        $base64    = $photo['data'] ?? '';
        // Utiliser le vrai nom du fichier local (ex: eleve_2_1777195075506.png)
        $filename  = $photo['filename']  ?? '';

        if (empty($base64) || empty($eleveId)) continue;

        // Decoder le base64
        $base64Clean = preg_replace('/^data:image\/[a-z]+;base64,/', '', $base64);
        $imageData   = base64_decode($base64Clean);
        if (!$imageData) {
            $results[] = ['eleve_id' => $eleveId, 'success' => false, 'message' => 'Base64 invalide'];
            continue;
        }

        // Si pas de filename fourni, construire depuis matricule ou eleve_id
        if (empty($filename)) {
            $filename = ($matricule ?: 'eleve_' . $eleveId) . '.' . $ext;
        }
        $dest = $dir . $filename;

        if (file_put_contents($dest, $imageData) !== false) {
            // Mettre a jour la BD
            try {
                $stmt = $pdo->prepare("UPDATE eleves SET photo = ? WHERE id = ?");
                $stmt->execute([$filename, $eleveId]);
            } catch (Exception $e) {}
            $results[] = ['eleve_id' => $eleveId, 'success' => true, 'filename' => $filename];
        } else {
            $results[] = ['eleve_id' => $eleveId, 'success' => false, 'message' => 'Erreur ecriture'];
        }
    }

    $ok = count(array_filter($results, fn($r) => $r['success']));
    echo json_encode([
        'success' => true,
        'uploaded' => $ok,
        'total'    => count($results),
        'results'  => $results
    ]);
}

// ── Debug chemin
function handleDebugPath() {
    $dir         = __DIR__ . '/../photos_eleves/';
    $dirExists   = is_dir($dir);
    $dirWritable = $dirExists && is_writable($dir);
    $files       = $dirExists ? scandir($dir) : [];
    echo json_encode([
        'success'    => true,
        '__DIR__'    => __DIR__,
        'photos_dir' => $dir,
        'exists'     => $dirExists,
        'writable'   => $dirWritable,
        'nb_files'   => count($files) - 2,
        'files'      => array_slice($files, 2, 5)
    ]);
}

// ── Ping
function handlePing($pdo) {
    echo json_encode([
        'success' => true,
        'message' => 'Piaschool Sync API operationnelle',
        'version' => '1.0.0',
        'time'    => date('Y-m-d H:i:s')
    ]);
}

// ── Status
function handleStatus($pdo) {
    try {
        $stmt = $pdo->query("
            SELECT table_name, records_synced, status, synced_at
            FROM sync_logs ORDER BY synced_at DESC LIMIT 30
        ");
        $logs = $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (Exception $e) {
        $logs = [];
    }

    $counts = [];
    foreach (getAllowedTables() as $t) {
        try {
            $check = $pdo->query("SHOW TABLES LIKE '$t'");
            if ($check->rowCount() > 0) {
                $s = $pdo->query("SELECT COUNT(*) as nb FROM `$t`");
                $counts[$t] = (int)$s->fetch(PDO::FETCH_ASSOC)['nb'];
            } else {
                $counts[$t] = 'TABLE MANQUANTE';
            }
        } catch (Exception $e) {
            $counts[$t] = 'ERREUR: ' . $e->getMessage();
        }
    }

    echo json_encode([
        'success' => true,
        'counts'  => $counts,
        'logs'    => $logs
    ]);
}

// ─