<?php
/**
 * Funciones auxiliares compartidas por el ETL
 */

/**
 * Convierte un string de WIN1252 a UTF-8.
 * Si el valor ya es UTF-8 válido, lo devuelve sin cambios.
 */
function toUtf8(?string $val, string $srcEncoding = 'WIN1252'): ?string {
    if ($val === null) return null;
    if (mb_check_encoding($val, 'UTF-8')) return $val;
    return iconv($srcEncoding, 'UTF-8//TRANSLIT//IGNORE', $val);
}

/**
 * Convierte un array completo de strings (resultado de Firebird) a UTF-8.
 */
function rowToUtf8(array $row, string $srcEncoding = 'WIN1252'): array {
    foreach ($row as $k => $v) {
        if (is_string($v)) {
            $row[$k] = toUtf8($v, $srcEncoding);
        }
    }
    return $row;
}

/**
 * Limpia un VARCHAR de Firebird: recorta espacios y convierte encoding.
 */
function cleanStr(?string $val, string $srcEncoding = 'WIN1252'): ?string {
    if ($val === null) return null;
    $val = trim(toUtf8($val, $srcEncoding) ?? '');
    return $val === '' ? null : $val;
}

/**
 * Convierte fecha Firebird (puede ser DATE o string 'YYYY-MM-DD') a MySQL DATE.
 * Devuelve null si la fecha es inválida o vacía.
 */
function fbDate($val): ?string {
    if ($val === null) return null;
    if ($val instanceof DateTime) return $val->format('Y-m-d');
    $str = trim((string)$val);
    if ($str === '' || $str === '0000-00-00') return null;
    try {
        return (new DateTime($str))->format('Y-m-d');
    } catch (\Exception $e) {
        return null;
    }
}

/**
 * INSERT en batch.
 * $pdo    → conexión MySQL
 * $table  → nombre de la tabla
 * $rows   → array de arrays asociativos con los mismos keys
 * $ignore → usa INSERT IGNORE para saltar duplicados
 */
function batchInsert(PDO $pdo, string $table, array $rows, bool $ignore = false): int {
    if (empty($rows)) return 0;

    $cols    = array_keys($rows[0]);
    $colList = implode(', ', array_map(fn($c) => "`$c`", $cols));
    $phRow   = '(' . implode(', ', array_fill(0, count($cols), '?')) . ')';

    $inserted = 0;
    foreach (array_chunk($rows, 500) as $chunk) {
        $placeholders = implode(', ', array_fill(0, count($chunk), $phRow));
        $keyword      = $ignore ? 'INSERT IGNORE' : 'INSERT';
        $sql          = "$keyword INTO `$table` ($colList) VALUES $placeholders";
        $flat         = array_merge(...array_map('array_values', $chunk));
        $stmt         = $pdo->prepare($sql);
        $stmt->execute($flat);
        $inserted    += $stmt->rowCount();
    }
    return $inserted;
}

/** Escribe al log y a stdout simultáneamente. */
function etlLog(string $msg, $logFp = null): void {
    $line = '[' . date('H:i:s') . '] ' . $msg . PHP_EOL;
    echo $line;
    if ($logFp) fwrite($logFp, $line);
}

/** Devuelve conteo de filas de una tabla Firebird. */
function fbCount(PDO $fb, string $table): int {
    return (int) $fb->query("SELECT COUNT(*) FROM $table")->fetchColumn();
}
