<?php
declare(strict_types=1);
require_once __DIR__.'/auth.php';
require_once __DIR__.'/conexao.php';
require_once __DIR__.'/inventario_mobile_helpers.php';
date_default_timezone_set('America/Sao_Paulo');
if(function_exists('tiPermExigir'))tiPermExigir($mysqli,'inventario_mobile','visualizar');
$mysqli->set_charset('utf8mb4');
if(!mobTableExists($mysqli,'ti_mobile_dispositivos'))mobRedirect('instalar_inventario_mobile.php');
$cfg=mobConfig($mysqli);$flash=mobGetFlash();
$q=mobText($_GET['q']??'',120);$tipo=mobText($_GET['tipo']??'',20);$estado=mobText($_GET['estado']??'',20);$setor=mobText($_GET['setor']??'',160);$android=mobText($_GET['android']??'',40);$alerta=mobText($_GET['alerta']??'',20);$pagina=max(1,(int)($_GET['pagina']??1));$limite=40;$offset=($pagina-1)*$limite;
$where=['1=1'];$types='';$vals=[];
if($q!==''){$where[]='(d.agent_id LIKE ? OR d.patrimonio LIKE ? OR d.modelo LIKE ? OR d.fabricante LIKE ? OR d.marca LIKE ? OR d.responsavel_nome LIKE ? OR d.setor LIKE ? OR d.numero_serie_manual LIKE ? OR d.imei_manual LIKE ? OR d.ip_local LIKE ?)';$x='%'.$q.'%';for($i=0;$i<10;$i++){$types.='s';$vals[]=$x;}}
if($tipo!==''){$where[]='d.tipo_dispositivo=?';$types.='s';$vals[]=$tipo;}
if($setor!==''){$where[]='d.setor=?';$types.='s';$vals[]=$setor;}
$recentH=max(1,(int)($cfg['recent_hours']??2));$silentH=max($recentH,(int)($cfg['silent_hours']??24));$offlineH=max($silentH,(int)($cfg['offline_alert_hours']??168));
if($android!==''){$where[]='d.android_version=?';$types.='s';$vals[]=$android;}
if($estado==='RECENTE')$where[]="d.ultima_comunicacao>=DATE_SUB(NOW(),INTERVAL {$recentH} HOUR)";
elseif($estado==='SEM_COMUNICACAO')$where[]="d.ultima_comunicacao<DATE_SUB(NOW(),INTERVAL {$silentH} HOUR) AND d.ultima_comunicacao>=DATE_SUB(NOW(),INTERVAL {$offlineH} HOUR)";
elseif($estado==='OFFLINE')$where[]='(d.ultima_comunicacao IS NULL OR d.ultima_comunicacao<DATE_SUB(NOW(),INTERVAL '.max(1,(int)($cfg['offline_alert_hours']??168)).' HOUR))';
elseif($estado==='REVOGADO')$where[]="d.status='REVOGADO'";
if($alerta==='ABERTO')$where[]='EXISTS(SELECT 1 FROM ti_mobile_eventos e WHERE e.dispositivo_id=d.id AND e.resolvido=0 AND e.severidade IN (\'ATENCAO\',\'CRITICO\'))';
$w=implode(' AND ',$where);
$stmt=$mysqli->prepare("SELECT COUNT(*) total FROM ti_mobile_dispositivos d WHERE {$w}");if($types)$stmt->bind_param($types,...$vals);$stmt->execute();$total=(int)($stmt->get_result()->fetch_assoc()['total']??0);$stmt->close();
$stmt=$mysqli->prepare("SELECT d.*,(SELECT COUNT(*) FROM ti_mobile_eventos e WHERE e.dispositivo_id=d.id AND e.resolvido=0 AND e.severidade IN ('ATENCAO','CRITICO')) alertas_abertos FROM ti_mobile_dispositivos d WHERE {$w} ORDER BY FIELD(d.status,'ATIVO','PENDENTE','REVOGADO'),d.ultima_comunicacao DESC,d.id DESC LIMIT ? OFFSET ?");$t2=$types.'ii';$v2=[...$vals,$limite,$offset];$stmt->bind_param($t2,...$v2);$stmt->execute();$res=$stmt->get_result();$devices=[];while($x=$res->fetch_assoc())$devices[]=$x;$stmt->close();
$stats=['total'=>0,'tablets'=>0,'smartphones'=>0,'recentes'=>0,'sem_comunicacao'=>0,'offline'=>0,'storage'=>0,'alertas'=>0];$crit=max(1,(int)($cfg['storage_critical_percent']??10));
$r=$mysqli->query("SELECT COUNT(*) total,SUM(tipo_dispositivo='TABLET') tablets,SUM(tipo_dispositivo='SMARTPHONE') smartphones,SUM(status='ATIVO' AND ultima_comunicacao>=DATE_SUB(NOW(),INTERVAL {$recentH} HOUR)) recentes,SUM(status='ATIVO' AND ultima_comunicacao<DATE_SUB(NOW(),INTERVAL {$silentH} HOUR) AND ultima_comunicacao>=DATE_SUB(NOW(),INTERVAL {$offlineH} HOUR)) sem_comunicacao,SUM(status='ATIVO' AND (ultima_comunicacao IS NULL OR ultima_comunicacao<DATE_SUB(NOW(),INTERVAL {$offlineH} HOUR))) offline,SUM(armazenamento_total_mb>0 AND armazenamento_livre_mb/armazenamento_total_mb*100<={$crit}) storage FROM ti_mobile_dispositivos");if($r){$x=$r->fetch_assoc()?:[];foreach(array_keys($stats) as $k)if(isset($x[$k]))$stats[$k]=(int)$x[$k];}
$r=$mysqli->query("SELECT COUNT(*) c FROM ti_mobile_eventos WHERE resolvido=0 AND severidade IN ('ATENCAO','CRITICO')");if($r)$stats['alertas']=(int)($r->fetch_assoc()['c']??0);
$setores=[];$r=$mysqli->query("SELECT DISTINCT setor FROM ti_mobile_dispositivos WHERE setor IS NOT NULL AND setor<>'' ORDER BY setor");if($r)while($x=$r->fetch_assoc())$setores[]=$x['setor'];$androids=[];$r=$mysqli->query("SELECT DISTINCT android_version FROM ti_mobile_dispositivos WHERE android_version IS NOT NULL AND android_version<>'' ORDER BY android_version DESC");if($r)while($x=$r->fetch_assoc())$androids[]=$x['android_version'];$pages=max(1,(int)ceil($total/$limite));
function mobPage(int $p): string{$q=$_GET;$q['pagina']=$p;return '?'.http_build_query($q);} 
?>
<!doctype html><html lang="pt-BR"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><meta name="theme-color" content="#061f42"><title>Inventário Android | Manutenção TI</title><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap" rel="stylesheet"><link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet"><link href="inventario_mobile_style.css?v=1" rel="stylesheet"></head><body><div class="topline"></div><div class="gridbg"></div><div class="app">
<header class="header"><div class="header-inner"><div class="brand"><div class="logo"><img src="assets/logo_pref.jpg" alt="Prefeitura"></div><div><span class="eyebrow"><i class="bi bi-android2"></i>Inventário automatizado • Android</span><h1 class="title">Tablets & Smartphones</h1><p class="subtitle">Inventário técnico automático de dispositivos Android institucionais, comunicação periódica, hardware, armazenamento, aplicativos e mudanças detectadas.</p></div></div><nav class="nav"><?php if(mobApkExists()):?><a class="primary" href="downloads/Agente-TI-Extrema.apk"><i class="bi bi-android2"></i>Baixar APK</a><?php elseif(mobDebugApkExists()):?><a class="primary" href="downloads/Agente-TI-Extrema-debug.apk"><i class="bi bi-android2"></i>Baixar APK de teste</a><?php elseif(mobAgentSourceExists()):?><a class="primary" href="downloads/Agente-TI-Extrema-FONTE.zip"><i class="bi bi-code-square"></i>Projeto Android</a><?php endif;?><a href="inventario_mobile_alertas.php"><i class="bi bi-bell-fill"></i>Alertas</a><a href="inventario_mobile_config.php"><i class="bi bi-gear-fill"></i>Configurar</a><a href="listar_os.php"><i class="bi bi-arrow-left-circle-fill"></i>Sistema</a></nav></div></header>
<main class="main"><?php if($flash):?><div class="flash <?=$flash['tipo']==='ok'?'ok':'err'?>"><i class="bi <?=$flash['tipo']==='ok'?'bi-check-circle-fill':'bi-exclamation-triangle-fill'?>"></i><?=mobE($flash['msg'])?></div><?php endif;?>
<?php if(!mobApkExists()&&mobDebugApkExists()):?><div class="flash ok"><i class="bi bi-info-circle-fill"></i>O <strong>APK de homologação</strong> está disponível e pode ser usado nos testes. A versão oficial de produção aparecerá depois que <strong>Agente-TI-Extrema.apk</strong> for assinado com a chave institucional.</div><?php elseif(!mobApkExists()):?><div class="flash err"><i class="bi bi-android2"></i>Nenhum APK instalável foi publicado. Envie o arquivo para <strong>downloads/Agente-TI-Extrema.apk</strong> ou, para homologação, <strong>downloads/Agente-TI-Extrema-debug.apk</strong>.</div><?php endif;?>
<section class="hero"><div><h2>Uma base viva dos dispositivos <span>Android da Prefeitura.</span></h2><p>O agente registra a configuração técnica e mantém a última comunicação atualizada. O módulo foi feito para tablets e também funciona em smartphones Android. O cadastro patrimonial de Smartphones continua existindo normalmente: este módulo adiciona a camada automática de inventário.</p><div class="tags"><span class="tag"><i class="bi bi-tablet-fill"></i>Tablets</span><span class="tag"><i class="bi bi-phone-fill"></i>Smartphones Android</span><span class="tag"><i class="bi bi-device-ssd-fill"></i>Hardware</span><span class="tag"><i class="bi bi-battery-half"></i>Bateria</span><span class="tag"><i class="bi bi-clock-history"></i>Histórico</span><span class="tag"><i class="bi bi-shield-lock-fill"></i>Token individual</span><span class="tag"><i class="bi bi-android2"></i>Agente <?=mobE($cfg['current_app_version']??'1.0.0')?><?=mobApkPublishedAt()?' • publicado '.mobE(mobApkPublishedAt()):''?></span></div></div><aside class="hero-side"><small>Cobertura automatizada</small><strong><?=$stats['total']?> dispositivos</strong><span><?=$stats['recentes']?> comunicaram nas últimas <?=$recentH?> horas. Sincronização padrão: a cada <?=(int)($cfg['sync_interval_min']??30)?> minutos, sujeita às regras de economia de bateria do Android.</span></aside></section>
<section class="kpis"><article class="kpi"><i class="bi bi-phone-fill"></i><strong><?=$stats['total']?></strong><span>Total gerenciado</span></article><article class="kpi"><i class="bi bi-tablet-fill"></i><strong><?=$stats['tablets']?></strong><span>Tablets</span></article><article class="kpi"><i class="bi bi-phone"></i><strong><?=$stats['smartphones']?></strong><span>Smartphones</span></article><article class="kpi"><i class="bi bi-broadcast-pin"></i><strong><?=$stats['recentes']?></strong><span>Comunicação recente</span></article><article class="kpi"><i class="bi bi-hourglass-split"></i><strong><?=$stats['sem_comunicacao']?></strong><span>Sem comunicação</span></article><article class="kpi"><i class="bi bi-wifi-off"></i><strong><?=$stats['offline']?></strong><span>Offline prolongado</span></article><article class="kpi"><i class="bi bi-device-ssd"></i><strong><?=$stats['storage']?></strong><span>Armazenamento crítico</span></article><article class="kpi"><i class="bi bi-exclamation-triangle-fill"></i><strong><?=$stats['alertas']?></strong><span>Alertas abertos</span></article></section>
<section class="panel"><div class="panel-head"><div class="panel-title"><span class="picon"><i class="bi bi-android2"></i></span><div><h3>Dispositivos gerenciados</h3><p><?=$total?> resultado(s) para os filtros atuais.</p></div></div><a class="btn primary" href="inventario_mobile_config.php#ativacao"><i class="bi bi-plus-circle-fill"></i>Ativar novo dispositivo</a></div>
<form class="filters" method="get"><input class="control" type="search" name="q" value="<?=mobE($q)?>" placeholder="Patrimônio, modelo, responsável, agente, série, IMEI ou IP"><select class="control" name="tipo"><option value="">Todos os tipos</option><option value="TABLET" <?=$tipo==='TABLET'?'selected':''?>>Tablets</option><option value="SMARTPHONE" <?=$tipo==='SMARTPHONE'?'selected':''?>>Smartphones</option><option value="OUTRO" <?=$tipo==='OUTRO'?'selected':''?>>Outros</option></select><select class="control" name="estado"><option value="">Toda comunicação</option><option value="RECENTE" <?=$estado==='RECENTE'?'selected':''?>>Comunicação recente</option><option value="SEM_COMUNICACAO" <?=$estado==='SEM_COMUNICACAO'?'selected':''?>>Sem comunicação</option><option value="OFFLINE" <?=$estado==='OFFLINE'?'selected':''?>>Offline prolongado</option><option value="REVOGADO" <?=$estado==='REVOGADO'?'selected':''?>>Revogados</option></select><select class="control" name="setor"><option value="">Todos os setores</option><?php foreach($setores as $s):?><option value="<?=mobE($s)?>" <?=$setor===$s?'selected':''?>><?=mobE($s)?></option><?php endforeach;?></select><select class="control" name="android"><option value="">Todas as versões Android</option><?php foreach($androids as $v):?><option value="<?=mobE($v)?>" <?=$android===$v?'selected':''?>>Android <?=mobE($v)?></option><?php endforeach;?></select><select class="control" name="alerta"><option value="">Com ou sem alertas</option><option value="ABERTO" <?=$alerta==='ABERTO'?'selected':''?>>Somente com alertas</option></select><button class="btn primary" type="submit"><i class="bi bi-search"></i>Filtrar</button></form>
<div class="table-wrap"><table class="data"><thead><tr><th>Dispositivo</th><th>Patrimônio</th><th>Responsável / setor</th><th>Android</th><th>Hardware</th><th>Armazenamento</th><th>Rede</th><th>Comunicação</th><th>Condição</th><th style="text-align:right">Ações</th></tr></thead><tbody><?php foreach($devices as $d):$state=mobEstadoComunicacao($d['ultima_comunicacao'],$offlineH);$score=mobScore($d,$cfg);$storageTotal=max(1,(int)$d['armazenamento_total_mb']);$storageFree=(int)$d['armazenamento_livre_mb'];$storagePct=round($storageFree/$storageTotal*100);?><tr><td data-label="Dispositivo"><div class="device"><span class="devicon"><i class="bi <?=$d['tipo_dispositivo']==='TABLET'?'bi-tablet-fill':'bi-phone-fill'?>"></i></span><span><strong><?=mobE(trim(($d['fabricante']?:$d['marca']).' '.($d['modelo']?:'Android'))) ?></strong><small><?=mobE($d['agent_id']?:'Agente pendente')?> • <?=mobE($d['tipo_dispositivo'])?></small></span></div></td><td data-label="Patrimônio"><span class="cell-main"><?=mobE($d['patrimonio']?:'Não informado')?></span><span class="cell-sub"><?=mobE($d['numero_serie_manual']?:($d['imei_manual']?'IMEI '.$d['imei_manual']:'Sem série/IMEI'))?></span></td><td data-label="Responsável"><span class="cell-main"><?=mobE($d['responsavel_nome']?:'Sem responsável')?></span><span class="cell-sub"><?=mobE($d['setor']?:'Sem setor')?></span></td><td data-label="Android"><span class="cell-main">Android <?=mobE($d['android_version']?:'?')?></span><span class="cell-sub">API <?=(int)($d['sdk_int']??0)?> • patch <?=mobE($d['security_patch']?:'não informado')?></span></td><td data-label="Hardware"><span class="cell-main"><?=number_format(((int)$d['ram_total_mb'])/1024,1,',','.')?> GB RAM</span><span class="cell-sub"><?=(int)($d['cpu_cores']??0)?> núcleos • <?=mobE($d['arquitetura']?:'arquitetura n/i')?></span></td><td data-label="Armazenamento"><span class="cell-main"><?=number_format($storageFree/1024,1,',','.')?> GB livres</span><span class="cell-sub"><?=$storagePct?>% livre de <?=number_format($storageTotal/1024,1,',','.')?> GB</span></td><td data-label="Rede"><span class="cell-main"><?=mobE($d['ip_local']?:'Sem IP')?></span><span class="cell-sub"><?=mobE($d['rede_tipo']?:'Rede não informada')?></span></td><td data-label="Comunicação"><span class="state <?=$state['class']?>"><i class="bi bi-circle-fill"></i><?=mobE($state['label'])?></span><span class="cell-sub">há <?=mobE(mobAgo($d['ultima_comunicacao']))?></span></td><td data-label="Condição"><div class="health"><strong><?=$score?>/100</strong><span class="healthbar"><span style="width:<?=$score?>%"></span></span></div><span class="cell-sub"><?=(int)$d['alertas_abertos']?> alerta(s)</span></td><td data-label="Ações"><div class="actions"><a class="mini primary" href="inventario_dispositivo.php?id=<?=(int)$d['id']?>"><i class="bi bi-eye-fill"></i>Ficha</a><?php if($d['vinculo_smartphone_id']):?><a class="mini" href="smartphones.php?buscar=<?=urlencode((string)$d['patrimonio'])?>"><i class="bi bi-link-45deg"></i>Cadastro</a><?php endif;?></div></td></tr><?php endforeach;?><?php if(!$devices):?><tr><td colspan="10"><div class="empty"><i class="bi bi-android2"></i><strong>Nenhum dispositivo encontrado</strong><span>Instale e ative o Agente TI Extrema em um tablet ou smartphone Android.</span></div></td></tr><?php endif;?></tbody></table></div>
<?php if($pages>1):?><div class="pager"><?php for($p=max(1,$pagina-3);$p<=min($pages,$pagina+3);$p++):?><a class="<?=$p===$pagina?'active':''?>" href="<?=mobE(mobPage($p))?>"><?=$p?></a><?php endfor;?></div><?php endif;?></section>
<footer class="footer"><span>Prefeitura de Extrema • Gerência de Tecnologia • Inventário Android</span><span>Coleta técnica: identificação, hardware, armazenamento, bateria, rede e aplicativos. Sem captura de tela, mensagens, áudio, câmera ou localização GPS.</span></footer></main></div></body></html>
