<?php
// ================== CONFIG & ANTI-CUELGUES ==================
ini_set('display_errors', 0);
ini_set('log_errors', 1);
if (!is_dir(__DIR__.'/logs')) @mkdir(__DIR__.'/logs', 0775, true);
ini_set('error_log', __DIR__.'/logs/php_error.log');

ini_set('default_socket_timeout', 6);
imap_timeout(IMAP_OPENTIMEOUT, 5);
imap_timeout(IMAP_READTIMEOUT, 5);
imap_timeout(IMAP_WRITETIMEOUT, 5);
ini_set('memory_limit', '128M');
// set_time_limit(25); // si tu hosting lo permite, puedes quitar el límite

// ====== Límites ======
define('MAX_MSGS_PER_ACCOUNT', 150);   // 0 = sin límite; usa 150 para no abusar
define('SEND_EML', false);
$__START = microtime(true);

// ====== Lock anti-solapes (15 min) ======
$LOCK = __DIR__.'/.apimydisney.lock';
if (file_exists($LOCK) && (time() - filemtime($LOCK)) < 900) { exit("locked\n"); }
@touch($LOCK);
register_shutdown_function(function() use ($LOCK){ @unlink($LOCK); });

// ================== PARÁMETROS MANUALES ==================
// ?from_zero=1  -> procesa TODO (ignora caché)
// ?reset=1      -> borra caché y siembra desde 0
// ?seed_days=N  -> si no hay caché, siembra al máximo UID de los últimos N días
$FROM_ZERO   = isset($_GET['from_zero']) && $_GET['from_zero']=='1';
$RESET_CACHE = isset($_GET['reset']) && $_GET['reset']=='1';
$SEED_DAYS   = isset($_GET['seed_days']) ? max(0, (int)$_GET['seed_days']) : 0;

// ================== TELEGRAM ==================
$telegramToken  = "8331191095:AAHCmWhEv6ck-CGAdggjKzaJOtOl4FIGiA0";
$telegramChatId = "659711952";

// ================== CACHE UID ==================
$UID_CACHE_FILE = __DIR__.'/uid_cache.json';
if ($RESET_CACHE && is_file($UID_CACHE_FILE)) { @unlink($UID_CACHE_FILE); }
$uidCache = [];
if (is_file($UID_CACHE_FILE)) {
    $json = @file_get_contents($UID_CACHE_FILE);
    $tmp = @json_decode($json, true);
    if (is_array($tmp)) $uidCache = $tmp;
}
function get_last_uid($user) {
    global $uidCache; return isset($uidCache[$user]) ? (int)$uidCache[$user] : 0;
}
function set_last_uid($user, $uid) {
    global $uidCache, $UID_CACHE_FILE;
    $uidCache[$user] = (int)$uid;
    @file_put_contents($UID_CACHE_FILE, json_encode($uidCache, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
}

// ================== IMAP MAP COMPLETO ==================
$imapServers = [
'andoguez.com'                  => ['host' => 'mail.andoguez.com',     'username' => 'admin@andoguez.com',     'password' => 'ANDRES12345@.'],
'blan.pro'                      => ['host' => 'mail.bomyn.com',        'username' => 'admin@bomyn.com',        'password' => 'ANDRES12345@.'],
'bloss.live'                    => ['host' => 'mail.bloss.live',       'username' => 'admin@bloss.live',       'password' => 'ANDRES12345@.'],
'blossen.com'                   => ['host' => 'mail.blossen.com',      'username' => 'admin@blossen.com',      'password' => 'ANDRES12345@.'],
'bomyn.com'                     => ['host' => 'mail.bomyn.com',        'username' => 'admin@bomyn.com',        'password' => 'ANDRES12345@.'],
'boomacount.net'                => ['host' => 'mail.boomacount.net',   'username' => 'admin@boomacount.net',   'password' => 'ANDRES12345@.'],
'breyles.com.co'                => ['host' => 'mail.breyles.com.co',   'username' => 'admin@breyles.com.co',   'password' => 'ANDRES12345@.'],
'cassacam.com'                  => ['host' => 'mail.cassacam.com',     'username' => 'admin@cassacam.com',     'password' => 'ANDRES12345@.'],
'casspim.com'                   => ['host' => 'mail.casspim.com',      'username' => 'admin@casspim.com',      'password' => 'ANDRES12345@.'],
'cassprime.com'                 => ['host' => 'mail.cassprime.com',    'username' => 'admin@cassprime.com',    'password' => 'ANDRES12345@.'],
'cassplus.co'                   => ['host' => 'mail.cassplus.co',      'username' => 'admin@cassplus.co',      'password' => 'ANDRES12345@.'],
'cassrun.com'                   => ['host' => 'mail.cassrun.com',      'username' => 'admin@cassrun.com',      'password' => 'ANDRES12345@.'],
'casston.com'                   => ['host' => 'mail.casston.com',      'username' => 'admin@casston.com',      'password' => 'ANDRES12345@.'],
'crotman.com'                   => ['host' => 'mail.crotman.com',      'username' => 'admin@crotman.com',      'password' => 'ANDRES12345@.'],
'crotmen.com'                   => ['host' => 'mail.crotmen.com',      'username' => 'admin@crotmen.com',      'password' => 'ANDRES12345@.'],
'crismoren.com'                 => ['host' => 'mail.crismoren.com',    'username' => 'admin@crismoren.com',    'password' => 'ANDRES12345@.'],
'darprim.com'                   => ['host' => 'mail.darprim.com',      'username' => 'admin@darprim.com',      'password' => 'ANDRES12345@.'],
'daykgv.com'                    => ['host' => 'mail.daykgv.com',       'username' => 'admin@daykgv.com',       'password' => 'ANDRES12345@.'],
'digitalworld26.com'            => ['host' => 'mail.digitalworld26.com','username' => 'admin@digitalworld26.com','password' => 'ANDRES12345@.'],
'disneyk.com'                   => ['host' => 'mail.disneyk.com',      'username' => 'admin@disneyk.com',      'password' => 'ANDRES12345@.'],
'fodenx.com.co'                 => ['host' => 'mail.fodenx.com.co',    'username' => 'admin@fodenx.com.co',    'password' => 'ANDRES12345@.'],
'hincca.com'                    => ['host' => 'mail.crotman.com',      'username' => 'admin@crotman.com',      'password' => 'ANDRES12345@.'],
'innurban.com.co'               => ['host' => 'mail.innurban.com.co',  'username' => 'admin@innurban.com.co',  'password' => 'BREINER12345@'],
'karpoolbar.com'                => ['host' => 'mail.crotman.com',      'username' => 'admin@crotman.com',      'password' => 'ANDRES12345@.'],
'kgvcolombia.com'               => ['host' => 'mail.kgvcolombia.com',  'username' => 'admin@kgvcolombia.com',  'password' => 'ANDRES12345@.'],
'kgvpro.co'                     => ['host' => 'mail.kgvpro.co',        'username' => 'admin@kgvpro.co',        'password' => 'ANDRES12345@.'],
'kgvweb.com'                    => ['host' => 'mail.kgvweb.com',       'username' => 'admin@kgvweb.com',       'password' => 'ANDRES12345@.'],
'mosflow.com'                   => ['host' => 'mail.mosflow.com',      'username' => 'admin@mosflow.com',      'password' => 'ANDRES12345@.'],
'multipross.com'                => ['host' => 'mail.multipross.com',   'username' => 'admin@multipross.com',   'password' => 'ANDRES12345@.'],
'mundoprim.com'                 => ['host' => 'mail.mundoprim.com',    'username' => 'admin@mundoprim.com',    'password' => 'ANDRES12345@.'],
'orega.live'                    => ['host' => 'mail.orega.live',       'username' => 'admin@orega.live',       'password' => 'ANDRES12345@.'],
'panbano.com'                   => ['host' => 'mail.panbano.com',      'username' => 'admin@panbano.com',      'password' => 'ANDRES12345@.'],
'pepeblender.com'               => ['host' => 'mail.crotman.com',      'username' => 'admin@crotman.com',      'password' => 'ANDRES12345@.'],
'pepevampiro.com.co'            => ['host' => 'mail.fodenx.com.co',    'username' => 'admin@fodenx.com.co',    'password' => 'ANDRES12345@.'],
'percloro.com'                  => ['host' => 'mail.crotman.com',      'username' => 'admin@crotman.com',      'password' => 'ANDRES12345@.'],
'peryes.com.co'                 => ['host' => 'mail.peryes.com.co',    'username' => 'admin@peryes.com.co',    'password' => 'ANDRES12345@.'],
'piniguini.com.co'              => ['host' => 'mail.cassrun.com',      'username' => 'admin@cassrun.com',      'password' => 'ANDRES12345@.'],
'prruebas.com'                  => ['host' => 'mail.prruebas.com',     'username' => 'admin@prruebas.com',     'password' => 'ANDRES12345@.'],
'puntilla.com.co'               => ['host' => 'mail.puntilla.com.co',  'username' => 'admin@puntilla.com.co',  'password' => 'ANDRES12345@.'],
'restablecimientosnetyotras.com'=> ['host' => 'mail.restablecimientosnetyotras.com','username' => 'admin@restablecimientosnetyotras.com','password' => 'ANDRES12345@.'],
'tegatea.com.co'                => ['host' => 'mail.tegatea.com.co',   'username' => 'admin@tegatea.com.co',   'password' => 'ANDRES12345@.'],
'tegateapepe.com.co'            => ['host' => 'mail.prruebas.com',     'username' => 'admin@prruebas.com',     'password' => 'ANDRES12345@.'],
'terquillo.com.co'              => ['host' => 'mail.orega.live',       'username' => 'admin@orega.live',       'password' => 'ANDRES12345@.'],
'tulijo.com'                    => ['host' => 'mail.tulijo.com',       'username' => 'admin@tulijo.com',       'password' => 'ANDRES12345@.'],
'toncass.com'                   => ['host' => 'mail.toncass.com',      'username' => 'admin@toncass.com',      'password' => 'ANDRES12345@.'],
'vivicass.com'                  => ['host' => 'mail.vivicass.com',     'username' => 'admin@vivicass.com',     'password' => 'ANDRES12345@.'],
'vixca.co'                      => ['host' => 'mail.vixca.co',         'username' => 'admin@vixca.co',         'password' => 'ANDRES12345@.'],
'vixcasts.com'                  => ['host' => 'mail.vixcasts.com',     'username' => 'admin@vixcasts.com',     'password' => 'ANDRES12345@.'],
'vixlion.com'                   => ['host' => 'mail.vixlion.com',      'username' => 'admin@vixlion.com',      'password' => 'ANDRES12345@.'],
'willamot.com'                  => ['host' => 'mail.willamot.com',     'username' => 'admin@willamot.com',     'password' => 'ANDRES12345@.'],
'ymails.cl'                     => ['host' => 'mail.innurban.com.co',  'username' => 'admin@innurban.com.co',  'password' => 'BREINER12345@'],
'ytmail.in'                     => ['host' => 'mail.ytmail.in',        'username' => 'admin@ytmail.in',        'password' => 'ANDRES12345@.'],
'ytmail.us'                     => ['host' => 'mail.ytmail.us',        'username' => 'admin@ytmail.us',        'password' => 'ANDRES12345@.'],
'amexi.top'                     => ['host' => 'mail.amexi.top',        'username' => 'admin@amexi.top',        'password' => 'ANDRES1003@#'],
'brixo.top'                     => ['host' => 'mail.brixo.top',        'username' => 'admin@brixo.top',        'password' => 'ANDRES1003@#'],
'dexor.top'                     => ['host' => 'mail.dexor.top',        'username' => 'admin@dexor.top',        'password' => 'ANDRES1003@#'],

// ---- Correos personales al final ----
'amentretenimiento@outlook.com' => ['host' => 'mail.vixlion.com',      'username' => 'admin@vixlion.com',      'password' => 'ANDRES12345@.'],
'bohmx16@gmail.com'             => ['host' => 'imap.gmail.com',        'username' => 'bohmx16@gmail.com',      'password' => 'uikudwbxsdsqojjw'],
'carlitosperespaes@gmail.com'   => ['host' => 'imap.gmail.com',        'username' => 'carlitosperespaes@gmail.com', 'password' => 'hzlplwcstlqkpbgi'],
'dianaperez86f@outlook.com'     => ['host' => 'mail.vixlion.com',      'username' => 'admin@vixlion.com',      'password' => 'ANDRES12345@.'],
'espalzaluisa435@gmail.com'     => ['host' => 'imap.gmail.com',        'username' => 'espalzaluisa435@gmail.com', 'password' => 'uumdzhuzlembnsly'],
'helpnet2001@hotmail.com'       => ['host' => 'mail.ytmail.us',        'username' => 'admin@ytmail.us',        'password' => 'ANDRES12345@.'],
'karinaperez75d@outlook.com'    => ['host' => 'imap.gmail.com',        'username' => 'pabloquintero34044@gmail.com', 'password' => 'lkremlywhebtrshq'],
'magpmount@gmail.com'           => ['host' => 'mail.boomacount.net',   'username' => 'admin@boomacount.net',   'password' => 'ANDRES12345@.'],
'nueca028@gmail.com'            => ['host' => 'imap.gmail.com',        'username' => 'nueca028@gmail.com',     'password' => 'tmxyjvdzaqchqodz'],
'pabloquintero34044@gmail.com'  => ['host' => 'imap.gmail.com',        'username' => 'pabloquintero34044@gmail.com', 'password' => 'lkremlywhebtrshq'],
'perlagarcia13940@gmail.com'    => ['host' => 'imap.gmail.com',        'username' => 'perlagarcia13940@gmail.com', 'password' => 'ezruojmrhanwvjeg'],
'zapatajuan2447@outlook.com'    => ['host' => 'mail.prruebas.com',     'username' => 'admin@prruebas.com',     'password' => 'ANDRES12345@.'],
];

// ================== TELEGRAM helpers ==================
function _tg_post($token, $chatId, $text) {
    $url = "https://api.telegram.org/bot{$token}/sendMessage";
    $post = ['chat_id' => $chatId, 'text' => $text];
    @file_get_contents($url, false, stream_context_create([
        'http' => [
            'method'  => 'POST',
            'header'  => "Content-Type: application/x-www-form-urlencoded\r\n",
            'content' => http_build_query($post),
            'timeout' => 12
        ]
    ]));
}
$TG_BLOCKS = [];
function tg_buf_block($block) {
    global $TG_BLOCKS;
    if (!is_string($block)) return;
    $block = trim($block);
    if ($block === '') return;
    $TG_BLOCKS[] = $block;
}
function tg_buf($linea) { tg_buf_block($linea); }
function tg_flush() {
    global $TG_BLOCKS, $telegramToken, $telegramChatId;
    if (empty($TG_BLOCKS)) return;
    $MAX = 4096;
    $header = "🧾 Resumen IMAP/TTv\n";
    $headerLen = mb_strlen($header, 'UTF-8');
    $current = $header;
    foreach ($TG_BLOCKS as $block) {
        $maxForBlock = $MAX - $headerLen - 1;
        if (mb_strlen($block, 'UTF-8') > $maxForBlock) {
            $block = mb_substr($block, 0, $maxForBlock, 'UTF-8');
        }
        $candidate = $current . ($current === $header ? '' : "\n") . $block;
        if (mb_strlen($candidate, 'UTF-8') > $MAX) {
            _tg_post($telegramToken, $telegramChatId, $current);
            $current = $header . $block;
        } else {
            $current = $candidate;
        }
    }
    if (trim($current) !== trim($header)) { _tg_post($telegramToken, $telegramChatId, $current); }
    $TG_BLOCKS = [];
}
function tg_send_document($token, $chatId, $filePath, $caption = '') {
    if (!SEND_EML || !is_file($filePath) || !class_exists('CURLFile')) return;
    $url = "https://api.telegram.org/bot{$token}/sendDocument";
    $post = [
        'chat_id' => $chatId,
        'caption' => $caption,
        'document' => new CURLFile($filePath, 'message/rfc822', basename($filePath))
    ];
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 20);
    @curl_exec($ch);
    @curl_close($ch);
}

// ================== RED ==================
function puedeConectar($host, $port, $timeout = 5) {
    $ip = @gethostbyname($host);
    if (!$ip) return false;
    $errno = $errstr = null;
    $sock = @fsockopen($ip, $port, $errno, $errstr, $timeout);
    if ($sock) { fclose($sock); return true; }
    return false;
}

// ====== HTML -> texto plano ======
function html_to_plain_no_css($html) {
    if (!is_string($html) || $html === '') return '';
    $html = preg_replace('~<!--.*?-->~s', '', $html);
    $html = preg_replace('~<head\b[^>]*>.*?</head>~is', '', $html);
    $html = preg_replace('~<style\b[^>]*>.*?</style>~is', '', $html);
    $html = preg_replace('~<script\b[^>]*>.*?</script>~is', '', $html);
    $html = preg_replace('~<noscript\b[^>]*>.*?</noscript>~is', '', $html);
    $html = preg_replace('~<link\b[^>]*>~i', '', $html);
    $html = preg_replace('/\s*style=("|\')(.*?)\1/i', '', $html);
    $repl = [
        '~<br\s*/?>~i'  => "\n",
        '~</p>~i'       => "\n\n",
        '~</div>~i'     => "\n",
        '~</h[1-6]>~i'  => "\n",
        '~</li>~i'      => "\n",
        '~<li\b[^>]*>~i'=> "• ",
        '~</tr>~i'      => "\n",
        '~</td>~i'      => "\t",
        '~</th>~i'      => "\t",
    ];
    foreach ($repl as $rgx => $rep) $html = preg_replace($rgx, $rep, $html);
    $text = strip_tags($html);
    $text = html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    $text = preg_replace("/[ \t]+/", " ", $text);
    $text = preg_replace("/\n{3,}/", "\n\n", $text);
    return trim($text);
}
function decode_subject_safe($raw) {
    $out = '';
    foreach (imap_mime_header_decode($raw ?: '') as $part) {
        $cs = strtoupper($part->charset ?? 'UTF-8');
        if (!in_array($cs, mb_list_encodings())) $cs = 'UTF-8';
        $out .= mb_convert_encoding($part->text, 'UTF-8', $cs);
    }
    return $out ?: '(Sin asunto)';
}
function get_best_body_plain($inbox, $msgno) {
    $structure = imap_fetchstructure($inbox, $msgno);
    $txt = '';
    $decode = function($raw, $enc) {
        if ($enc == 3) return imap_base64($raw);
        if ($enc == 4) return imap_qprint($raw);
        if ($enc == 2) return imap_binary($raw);
        return $raw;
    };
    if (isset($structure->parts)) {
        foreach ($structure->parts as $i => $part) {
            $sub = strtolower($part->subtype ?? '');
            $raw = imap_fetchbody($inbox, $msgno, $i+1);
            $raw = $decode($raw, $part->encoding ?? 0);
            if ($sub === 'plain') { $txt = $raw; break; }
            elseif ($sub === 'html' && $txt === '') { $txt = html_to_plain_no_css($raw); }
        }
    } else {
        $raw = imap_body($inbox, $msgno);
        $raw = $decode($raw, $structure->encoding ?? 0);
        if (stripos($raw, '<html') !== false || stripos($raw, '<body') !== false || stripos($raw, '<div') !== false) {
            $txt = html_to_plain_no_css($raw);
        } else { $txt = $raw; }
    }
    if ($txt === '') {
        $raw = imap_body($inbox, $msgno);
        $txt = html_to_plain_no_css($raw);
    }
    $txt = html_entity_decode($txt, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    $txt = preg_replace('/\s+/u', ' ', trim($txt));
    return $txt !== '' ? $txt : '(Sin contenido)';
}
function normalizar_cuerpo($txt) {
    $txt = preg_replace('/\bMyDisney\s+Email\b/i', ' ', $txt);
    $txt = html_entity_decode($txt, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    $txt = preg_replace('/\s+/u', ' ', trim($txt));
    return $txt;
}
function primera_oracion_limpia($txt) {
    $txt = normalizar_cuerpo($txt);
    $p = mb_strpos($txt, '.', 0, 'UTF-8');
    if ($p === false) return mb_substr($txt, 0, 300, 'UTF-8');
    return mb_substr($txt, 0, $p + 1, 'UTF-8');
}

// ====== Patrón multi-idioma (ES/EN/PT/FR/IT/DE/RU/JA/ZH) ======
$patternMyDisney = '/
\b(
    # Español
    (cuenta|contrase(?:ñ|n)a|correo\s+electr[oó]nico).{0,40}my\s*disney.{0,40}(actualizad[oa]|cambiad[oa])|
    # Inglés
    my\s*disney.{0,20}(account|password|email).{0,20}(updated|changed)|
    (your|the)\s+(my\s*disney).{0,30}(account|password|email).{0,20}(was|has\s+been)?\s*(updated|changed)|
    # Portugués
    (conta|senha|email).{0,30}my\s*disney.{0,30}(atualizad[ao]|alterad[ao]|mudad[ao])|
    # Francés
    (compte|mot\s*de\s*passe|courriel|e[-\s]?mail).{0,30}my\s*disney.{0,30}(mis[eé]\s*[àa]\s*jour|modifi[eé])|
    # Italiano
    (account|password|email).{0,30}my\s*disney.{0,30}(aggiornat[oa]|modificat[oa])|
    # Alemán
    (konto|passwort|e[-\s]?mail).{0,30}my\s*disney.{0,30}(aktualisiert|ge[aä]ndert)|
    # Ruso
    (аккаунт|пароль|почта).{0,30}my\s*disney.{0,30}(обновл[её]н|измен[её]н)|
    # Japonés
    my\s*disney.{0,20}(アカウント|パスワード|メール).{0,20}(更新|変更)(されました|しました)?|
    # Chino
    my\s*disney.{0,20}(账户|賬戶|密码|密碼|邮箱|郵箱|邮件|郵件).{0,20}(已?更新|已?更改|修改)
)\b
/iux';

// ================== PROCESO ==================
// Carpeta para EML
$emlDir = __DIR__ . '/eml';
if (SEND_EML && !is_dir($emlDir)) @mkdir($emlDir, 0775, true);

foreach ($imapServers as $name => $cfg) {

    $user = $cfg['username'];
    $host = $cfg['host'];
    $port = $cfg['port'] ?? 993;
    $ssl  = $cfg['ssl'] ?? true;

    // Precheck
    if (!puedeConectar($host, $port, 5)) {
        tg_buf("⛔ PRECHECK: {$user} — {$host}:{$port} sin respuesta");
        continue;
    }

    $flags   = '/imap' . ($ssl ? '/ssl/novalidate-cert' : '');
    $mailbox = "{".$host.":".$port.$flags."}INBOX";

    $t0 = microtime(true);
    $inbox = @imap_open($mailbox, $user, $cfg['password'], OP_READONLY, 1, ['DISABLE_AUTHENTICATOR' => 'GSSAPI']);
    if (!$inbox) {
        $err = imap_last_error() ?: 'Timeout/Desconocido';
        if (preg_match('/auth|invalid|login/i', $err)) {
            tg_buf("🔑 AUTH FAIL: {$user}@{$host}:{$port} — {$err}");
        } else {
            tg_buf("❌ IMAP FAIL: {$user}@{$host}:{$port} — {$err}");
        }
        continue;
    }

    // UIDs existentes
    $uids = @imap_search($inbox, 'ALL', SE_UID);
    if (!is_array($uids)) $uids = [];
    sort($uids, SORT_NUMERIC);

    // Punto de partida (resiliente si vaciaste bandeja)
    $last = get_last_uid($user);
    if ($FROM_ZERO) {
        $last = 0;
    } elseif ($last === 0) {
        if ($SEED_DAYS > 0) {
            $since = @imap_search($inbox, 'SINCE "' . date('d-M-Y', strtotime("-{$SEED_DAYS} days")) . '"', SE_UID);
            if (is_array($since) && !empty($since)) { $last = max($since); set_last_uid($user, (int)$last); }
        } elseif (!empty($uids)) {
            // si no hay caché previo, no proceses histórico viejo por defecto:
            $last = end($uids); set_last_uid($user, (int)$last);
        }
    } elseif ($last > 0 && !in_array($last, $uids, true)) {
        // ⚠️ El UID guardado ya no existe (probablemente vaciaste la bandeja)
        $last = 0; // vuelve a empezar para no “perder” lo nuevo
    }

    $newUids = array_values(array_filter($uids, fn($u) => (int)$u > $last));
    if (MAX_MSGS_PER_ACCOUNT > 0 && count($newUids) > MAX_MSGS_PER_ACCOUNT) {
        $newUids = array_slice($newUids, -MAX_MSGS_PER_ACCOUNT);
    }

    $maxHitUID = 0;
    $bloques = [];

    foreach ($newUids as $uid) {
        $msgno = imap_msgno($inbox, $uid);
        if (!$msgno) continue;

        $ovArr = imap_fetch_overview($inbox, $msgno, 0);
        $ov = $ovArr ? $ovArr[0] : (object)[];
        $subject = decode_subject_safe($ov->subject ?? '');
        $dateStr = $ov->date ?? '';
        $toLine  = $ov->to ?? '(desconocido)';

        $bodyFull  = get_best_body_plain($inbox, $msgno);
        $bodyShort = primera_oracion_limpia($bodyFull);

        $hit = (preg_match($patternMyDisney, $subject) === 1) ||
               (preg_match($patternMyDisney, $bodyFull) === 1);

        if (!$hit) continue;

        if ((int)$uid > $maxHitUID) $maxHitUID = (int)$uid;

        $fechaLocal = date('Y-m-d H:i:s', strtotime($dateStr ?: 'now'));
        $bloques[] =
            "📧 Asunto: {$subject}\n" .
            "📨 Para: {$toLine}\n" .
            "🕒 Fecha: {$fechaLocal}\n" .
            "📝 Cuerpo: {$bodyShort}\n" .
            "— — —";

        if (SEND_EML) {
            $headers = imap_fetchheader($inbox, $msgno, FT_PREFETCHTEXT);
            $rawBody = imap_body($inbox, $msgno, FT_PEEK);
            $emlRaw  = $headers . "\r\n" . $rawBody;
            $safeSubj  = preg_replace('/[^a-z0-9._ -]+/i', '_', $subject);
            $fname     = sprintf('%s_%s_%u.eml', date('Ymd_His'), mb_substr($safeSubj,0,40), $uid);
            $fpath     = __DIR__ . '/eml/' . $fname;
            @file_put_contents($fpath, $emlRaw);
            if (is_file($fpath)) {
                $caption = "EML | {$user} | UID {$uid} | {$fechaLocal}";
                tg_send_document($telegramToken, $telegramChatId, $fpath, $caption);
            }
        }

        usleep(100000); // 100ms para no saturar
    }

    // ====== Mensaje siempre por dominio ======
    if (!empty($bloques)) {
        tg_buf_block("🔔 Resumen MyDisney ({$user})\n".implode("\n", $bloques));
        // Avanza cache al mayor UID con hit (evita perderte tras borrados)
        if ($maxHitUID > 0) { set_last_uid($user, $maxHitUID); }
    } else {
        tg_buf_block("❎ {$user} no encontró nada");
        // Si no hubo hits pero hay mensajes nuevos, adelanta al último para no reprocesar eternamente
        if (!empty($newUids)) { set_last_uid($user, max($newUids)); }
    }

    imap_close($inbox);
    usleep(100000);
}

// Enviar todo junto
tg_flush();

echo "OK";