<?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');
$id=(int)($_GET['id']??$_POST['id']??0);$csrf=mobCsrf();$cfg=mobConfig($mysqli);$erro='';$flash=mobGetFlash();
function mobLoadDevice(mysqli $db,int $id):?array{$stmt=$db->prepare('SELECT * FROM ti_mobile_dispositivos WHERE id=? LIMIT 1');$stmt->bind_param('i',$id);$stmt->execute();$row=$stmt->get_result()->fetch_assoc();$stmt->close();return $row?:null;}
$d=mobLoadDevice($mysqli,$id);if(!$d){http_response_code(404);exit('Dispositivo não encontrado.');}
if($_SERVER['REQUEST_METHOD']==='POST'){
 try{mobCheckCsrf();$action=mobText($_POST['acao']??'',30);
  if($action==='cadastro'){
   $pat=mobNullable($_POST['patrimonio']??'',60);$resp=mobNullable($_POST['responsavel_nome']??'',160);$setor=mobNullable($_POST['setor']??'',180);$serial=mobNullable($_POST['numero_serie_manual']??'',120);$imei=mobNullable($_POST['imei_manual']??'',40);$notes=mobNullable($_POST['observacoes']??'',1000);
   foreach(['patrimonio'=>'Patrimônio','responsavel_nome'=>'Responsável','setor'=>'Setor'] as $key=>$label){$new=['patrimonio'=>$pat,'responsavel_nome'=>$resp,'setor'=>$setor][$key];if((string)($d[$key]??'')!==(string)$new){$stmt=$mysqli->prepare("INSERT INTO ti_mobile_eventos(dispositivo_id,tipo,severidade,titulo,valor_anterior,valor_novo,detalhes,origem) VALUES(?,?,'INFO',?,?,?,'Alteração administrativa registrada.','WEB')");$type='MUDANCA_'.strtoupper($key);$title=$label.' alterado';$old=(string)($d[$key]??'');$newValue=(string)$new;$stmt->bind_param('issss',$id,$type,$title,$old,$newValue);$stmt->execute();$stmt->close();}}
   $smart=mobLinkSmartphone($mysqli,$pat,$imei)??0;$asset=mobLinkAtivo($mysqli,$pat,$serial,$imei)??0;$stmt=$mysqli->prepare('UPDATE ti_mobile_dispositivos SET patrimonio=?,responsavel_nome=?,setor=?,numero_serie_manual=?,imei_manual=?,observacoes=?,vinculo_smartphone_id=NULLIF(?,0),vinculo_ativo_id=NULLIF(?,0) WHERE id=?');$stmt->bind_param('ssssssiii',$pat,$resp,$setor,$serial,$imei,$notes,$smart,$asset,$id);$stmt->execute();$stmt->close();mobAudit($mysqli,'CADASTRO_ATUALIZADO',$id);mobFlash('ok','Cadastro administrativo atualizado.');
  }elseif($action==='revogar'){
   if(!mobEhRenan())throw new RuntimeException('Somente Renan pode revogar agentes.');$user=mobUsuario();$stmt=$mysqli->prepare("UPDATE ti_mobile_dispositivos SET status='REVOGADO',revogado_em=NOW(),revogado_por=? WHERE id=?");$stmt->bind_param('si',$user,$id);$stmt->execute();$stmt->close();mobAudit($mysqli,'AGENTE_REVOGADO',$id);mobFlash('ok','Agente revogado; novas comunicações serão bloqueadas e auditadas.');
  }elseif($action==='nova_ativacao'){
   if(!mobEhRenan())throw new RuntimeException('Somente Renan pode reprovisionar agentes.');$code=strtoupper(substr(bin2hex(random_bytes(8)),0,4).'-'.substr(bin2hex(random_bytes(8)),0,4).'-'.substr(bin2hex(random_bytes(8)),0,4));$hash=hash('sha256',$code);$user=mobUsuario();$stmt=$mysqli->prepare('UPDATE ti_mobile_config SET enrollment_hash=?,enrollment_expires_at=DATE_ADD(NOW(),INTERVAL 24 HOUR),enrollment_uses_remaining=1,updated_by=? WHERE id=1');$stmt->bind_param('ss',$hash,$user);$stmt->execute();$stmt->close();$stmt=$mysqli->prepare("UPDATE ti_mobile_dispositivos SET status='PENDENTE' WHERE id=?");$stmt->bind_param('i',$id);$stmt->execute();$stmt->close();mobAudit($mysqli,'NOVA_ATIVACAO_GERADA',$id);mobFlash('ok','Código de reativação (24h, uso único): '.$code);
  }elseif(in_array($action,['reconhecer_evento','resolver_evento'],true)){
   $eventId=(int)($_POST['evento_id']??0);$user=mobUsuario();$note=mobNullable($_POST['observacao']??'',1000);if($action==='reconhecer_evento'){$stmt=$mysqli->prepare("UPDATE ti_mobile_eventos SET status_revisao='RECONHECIDO',reconhecido_por=?,reconhecido_em=NOW(),observacao_revisao=? WHERE id=? AND dispositivo_id=? AND resolvido=0");$stmt->bind_param('ssii',$user,$note,$eventId,$id);}else{$stmt=$mysqli->prepare("UPDATE ti_mobile_eventos SET status_revisao='RESOLVIDO',resolvido=1,resolvido_por=?,resolvido_em=NOW(),observacao_revisao=? WHERE id=? AND dispositivo_id=?");$stmt->bind_param('ssii',$user,$note,$eventId,$id);}$stmt->execute();$stmt->close();mobAudit($mysqli,strtoupper($action),$id);mobFlash('ok',$action==='resolver_evento'?'Alerta resolvido.':'Alerta reconhecido.');
  }
  mobRedirect('inventario_dispositivo.php?id='.$id);
 }catch(Throwable $e){$erro=$e->getMessage();}
}
$d=mobLoadDevice($mysqli,$id);$events=[];$stmt=$mysqli->prepare('SELECT * FROM ti_mobile_eventos WHERE dispositivo_id=? ORDER BY resolvido ASC,id DESC LIMIT 150');$stmt->bind_param('i',$id);$stmt->execute();$r=$stmt->get_result();while($x=$r->fetch_assoc())$events[]=$x;$stmt->close();
$apps=[];$stmt=$mysqli->prepare('SELECT * FROM ti_mobile_apps WHERE dispositivo_id=? AND ativo=1 ORDER BY obrigatorio DESC,instalado ASC,app_label LIMIT 300');$stmt->bind_param('i',$id);$stmt->execute();$r=$stmt->get_result();while($x=$r->fetch_assoc())$apps[]=$x;$stmt->close();
$syncs=[];$stmt=$mysqli->prepare('SELECT * FROM ti_mobile_sincronizacoes WHERE dispositivo_id=? ORDER BY id DESC LIMIT 50');$stmt->bind_param('i',$id);$stmt->execute();$r=$stmt->get_result();while($x=$r->fetch_assoc())$syncs[]=$x;$stmt->close();
$orders=[];if(mobTableExists($mysqli,'ordens_servico')){$terms=array_values(array_filter([$d['patrimonio'],$d['numero_serie_manual'],$d['imei_manual']]));if($terms){$conditions=[];$types='';$values=[];foreach($terms as $term){$conditions[]='patrimonio=? OR numero_serie=? OR problema LIKE ?';$types.='sss';$values[]=$term;$values[]=$term;$values[]='%'.$term.'%';}$stmt=$mysqli->prepare('SELECT * FROM ordens_servico WHERE '.implode(' OR ',$conditions).' ORDER BY id DESC LIMIT 80');$stmt->bind_param($types,...$values);$stmt->execute();$r=$stmt->get_result();while($x=$r->fetch_assoc())$orders[]=$x;$stmt->close();}}
$asset=null;if(!empty($d['vinculo_ativo_id'])&&mobTableExists($mysqli,'ti_ativos')){$stmt=$mysqli->prepare('SELECT id,codigo_ativo FROM ti_ativos WHERE id=?');$stmt->bind_param('i',$d['vinculo_ativo_id']);$stmt->execute();$asset=$stmt->get_result()->fetch_assoc();$stmt->close();}
$recent=(int)($cfg['recent_hours']??2);$silent=(int)($cfg['silent_hours']??24);$offline=(int)($cfg['offline_alert_hours']??168);$state=mobEstadoComunicacao($d['ultima_comunicacao'],$offline,$recent,$silent);$score=mobScore($d,$cfg);$freePct=(int)$d['armazenamento_total_mb']>0?round((int)$d['armazenamento_livre_mb']/(int)$d['armazenamento_total_mb']*100):0;$outdated=(int)($d['app_version_code']??0)<(int)($cfg['current_app_version_code']??1);
$osUrl='nova_os.php?'.http_build_query(['nome_solicitante'=>$d['responsavel_nome'],'setor'=>$d['setor'],'tipo_equipamento'=>$d['tipo_dispositivo']==='TABLET'?'Tablet':'Smartphone','marca'=>$d['fabricante']?:$d['marca'],'modelo'=>$d['modelo'],'patrimonio'=>$d['patrimonio'],'numero_serie'=>$d['numero_serie_manual'],'problema'=>$d['imei_manual']?'IMEI: '.$d['imei_manual'].' — ':'']);
?>
<!doctype html><html lang="pt-BR"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title><?=mobE($d['agent_id']?:'Dispositivo Android')?></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=2" rel="stylesheet"><style>.tabs{display:flex;gap:7px;overflow:auto;padding:12px}.tab{white-space:nowrap}.tab-content{display:none;padding:14px}.tab-content.active{display:block}</style></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><?=mobE($d['agent_id']?:'Agente Android')?></span><h1 class="title"><?=mobE(trim(($d['fabricante']?:$d['marca']).' '.($d['modelo']?:'Dispositivo Android')))?></h1><p class="subtitle">Patrimônio <?=mobE($d['patrimonio']?:'não informado')?> • Responsável: <?=mobE($d['responsavel_nome']?:'não informado')?> • Setor: <?=mobE($d['setor']?:'não informado')?> • última comunicação há <?=mobE(mobAgo($d['ultima_comunicacao']))?></p></div></div><nav class="nav"><a class="primary" href="inventario_equipamentos.php">Inventário</a><a href="<?=mobE($osUrl)?>"><i class="bi bi-tools"></i>Criar OS</a><?php if($asset):?><a href="central_ativos/ativo.php?id=<?=(int)$asset['id']?>"><i class="bi bi-box-seam"></i><?=mobE($asset['codigo_ativo'])?></a><?php endif;?></nav></div></header>
<main class="main"><?php if($erro):?><div class="flash err"><?=mobE($erro)?></div><?php endif;?><?php if($flash):?><div class="flash <?=$flash['tipo']==='ok'?'ok':'err'?>"><?=mobE($flash['msg'])?></div><?php endif;?><?php if($outdated):?><div class="flash err"><i class="bi bi-arrow-up-circle-fill"></i>Atualização recomendada: agente <?=mobE($d['app_version']?:'N/I')?>; versão atual <?=mobE($cfg['current_app_version']??'1.0.0')?>.</div><?php endif;?>
<section class="hero"><div><h2><?=mobE($d['agent_id'])?> <span><?=mobE($d['patrimonio']?:$d['tipo_dispositivo'])?></span></h2><p>Ficha técnica automática e histórico preservado do dispositivo institucional.</p><div class="tags"><span class="state <?=$state['class']?>"><i class="bi bi-circle-fill"></i><?=mobE($d['status']==='REVOGADO'?'Revogado':$state['label'])?></span><span class="tag">Condição <?=$score?>/100</span><span class="tag">Livre <?=$freePct?>%</span><span class="tag">Bateria <?=(int)($d['bateria_percentual']??0)?>%</span><?php if($asset):?><span class="tag">Ativo vinculado <?=mobE($asset['codigo_ativo'])?></span><?php endif;?></div></div><aside class="hero-side"><small>Última comunicação</small><strong><?=mobE(mobData($d['ultima_comunicacao']))?></strong><span>IP local <?=mobE($d['ip_local']?:'N/I')?> • agente <?=mobE($d['app_version']?:'N/I')?></span></aside></section>
<section class="panel"><div class="tabs"><?php foreach(['visao'=>'Visão geral','hardware'=>'Hardware','android'=>'Android','storage'=>'Armazenamento','battery'=>'Bateria','apps'=>'Aplicativos','network'=>'Rede','history'=>'Histórico','alerts'=>'Alertas','os'=>'OS','changes'=>'Alterações detectadas'] as $key=>$label):?><button class="btn tab <?=$key==='visao'?'primary':''?>" type="button" data-tab="<?=$key?>"><?=mobE($label)?></button><?php endforeach;?></div>
<div class="tab-content active" id="tab-visao"><div class="detail-grid"><div class="detail"><span>Patrimônio</span><strong><?=mobE($d['patrimonio']?:'N/I')?></strong></div><div class="detail"><span>Responsável</span><strong><?=mobE($d['responsavel_nome']?:'N/I')?></strong></div><div class="detail"><span>Setor</span><strong><?=mobE($d['setor']?:'N/I')?></strong></div><div class="detail"><span>Série / IMEI</span><strong><?=mobE(($d['numero_serie_manual']?:'N/I').' / '.($d['imei_manual']?:'N/I'))?></strong></div></div><form method="post" style="margin-top:14px"><input type="hidden" name="csrf_token" value="<?=mobE($csrf)?>"><input type="hidden" name="id" value="<?=$id?>"><input type="hidden" name="acao" value="cadastro"><div class="form-grid"><?php foreach(['patrimonio'=>'Patrimônio','responsavel_nome'=>'Responsável','setor'=>'Setor','numero_serie_manual'=>'Número de série','imei_manual'=>'IMEI'] as $key=>$label):?><div class="group"><label><?=$label?></label><input class="control" name="<?=$key?>" value="<?=mobE($d[$key])?>"></div><?php endforeach;?><div class="group full"><label>Observações</label><textarea class="control" name="observacoes"><?=mobE($d['observacoes'])?></textarea></div></div><div class="form-actions"><button class="btn primary">Salvar cadastro</button></div></form><?php if(mobEhRenan()):?><form method="post" class="form-actions"><input type="hidden" name="csrf_token" value="<?=mobE($csrf)?>"><input type="hidden" name="id" value="<?=$id?>"><input type="hidden" name="acao" value="<?=$d['status']==='REVOGADO'?'nova_ativacao':'revogar'?>"><button class="btn <?=$d['status']==='REVOGADO'?'green':'red'?>"><?=$d['status']==='REVOGADO'?'Gerar nova ativação':'Revogar agente'?></button></form><?php endif;?></div>
<div class="tab-content" id="tab-hardware"><div class="detail-grid"><div class="detail"><span>RAM</span><strong><?=number_format((int)$d['ram_total_mb']/1024,1,',','.')?> GB total • <?=number_format((int)$d['ram_disponivel_mb']/1024,1,',','.')?> GB livre</strong></div><div class="detail"><span>CPU</span><strong><?=(int)$d['cpu_cores']?> núcleos • <?=mobE($d['arquitetura'])?></strong></div><div class="detail"><span>Tela</span><strong><?=mobE($d['resolucao_tela'])?> • <?=mobE($d['densidade_tela'])?></strong></div></div></div>
<div class="tab-content" id="tab-android"><div class="detail-grid"><div class="detail"><span>Android / API</span><strong><?=mobE($d['android_version'])?> / <?=(int)$d['sdk_int']?></strong></div><div class="detail"><span>Security patch</span><strong><?=mobE($d['security_patch']?:'N/I')?></strong></div><div class="detail"><span>Build</span><strong><?=mobE($d['build_id'])?></strong></div><div class="detail"><span>Fingerprint</span><strong><?=mobE($d['build_fingerprint'])?></strong></div></div></div>
<div class="tab-content" id="tab-storage"><div class="detail-grid"><div class="detail"><span>Total</span><strong><?=number_format((int)$d['armazenamento_total_mb']/1024,1,',','.')?> GB</strong></div><div class="detail"><span>Usado</span><strong><?=number_format((int)($d['armazenamento_usado_mb']??0)/1024,1,',','.')?> GB</strong></div><div class="detail"><span>Livre</span><strong><?=number_format((int)$d['armazenamento_livre_mb']/1024,1,',','.')?> GB (<?=$freePct?>%)</strong></div></div></div>
<div class="tab-content" id="tab-battery"><div class="detail-grid"><div class="detail"><span>Carga</span><strong><?=(int)$d['bateria_percentual']?>%</strong></div><div class="detail"><span>Carregando</span><strong><?=!empty($d['bateria_carregando'])?'Sim':'Não'?></strong></div><div class="detail"><span>Status / fonte</span><strong><?=mobE($d['bateria_status'])?> • <?=mobE($d['bateria_fonte'])?></strong></div><div class="detail"><span>Temperatura</span><strong><?=mobE($d['bateria_temperatura']?:'N/I')?> °C</strong></div></div></div>
<div class="tab-content" id="tab-apps"><div class="table-wrap"><table class="data"><thead><tr><th>Aplicativo</th><th>Pacote</th><th>Versão</th><th>Situação</th></tr></thead><tbody><?php foreach($apps as $app):?><tr><td><?=mobE($app['app_label'])?></td><td><?=mobE($app['package_name'])?></td><td><?=mobE($app['version_name']?:'N/I')?></td><td><span class="state <?=$app['instalado']?'ok':'danger'?>"><?=$app['instalado']?'Instalado':'Ausente'?><?=$app['obrigatorio']?' • obrigatório':''?></span></td></tr><?php endforeach;?></tbody></table></div></div>
<div class="tab-content" id="tab-network"><div class="detail-grid"><div class="detail"><span>Conexão</span><strong><?=mobE($d['rede_tipo']?:'N/I')?></strong></div><div class="detail"><span>IP local</span><strong><?=mobE($d['ip_local']?:'N/I')?></strong></div><div class="detail"><span>Último IP remoto</span><strong><?=mobE($d['ultimo_ip_remoto']?:'N/I')?></strong></div><div class="detail"><span>Última comunicação</span><strong><?=mobE(mobData($d['ultima_comunicacao']))?></strong></div></div></div>
<div class="tab-content" id="tab-history"><div class="timeline"><?php foreach($syncs as $sync):?><article class="event"><span class="event-icon"><i class="bi bi-cloud-check-fill"></i></span><div><strong>Inventário recebido</strong><p>Agente <?=mobE($sync['app_version']?:'N/I')?> • IP <?=mobE($sync['ip_remoto']?:'N/I')?></p></div><time><?=mobE(mobData($sync['recebido_em']))?></time></article><?php endforeach;?></div></div>
<div class="tab-content" id="tab-alerts"><div class="timeline"><?php foreach(array_filter($events,fn($e)=>!$e['resolvido']&&in_array($e['severidade'],['ATENCAO','CRITICO'],true)) as $event):?><article class="event"><span class="event-icon"><i class="bi bi-exclamation-triangle-fill"></i></span><div><strong><?=mobE($event['titulo'])?></strong><p><?=mobE($event['detalhes']?:$event['valor_novo'])?></p><form method="post"><input type="hidden" name="csrf_token" value="<?=mobE($csrf)?>"><input type="hidden" name="id" value="<?=$id?>"><input type="hidden" name="evento_id" value="<?=(int)$event['id']?>"><input class="control" name="observacao" placeholder="Observação da revisão"><button class="mini" name="acao" value="reconhecer_evento">Reconhecer</button><button class="mini primary" name="acao" value="resolver_evento">Resolver</button></form></div><time><?=mobE(mobData($event['criado_em']))?></time></article><?php endforeach;?></div></div>
<div class="tab-content" id="tab-os"><div class="form-actions"><a class="btn primary" href="<?=mobE($osUrl)?>">Criar OS preenchida</a></div><div class="timeline"><?php foreach($orders as $order):?><article class="event"><span class="event-icon"><i class="bi bi-tools"></i></span><div><strong><?=mobE($order['numero_os']??('#'.$order['id']))?> • <?=mobE($order['status'])?></strong><p><?=mobE($order['problema'])?></p></div><time><?=mobE(mobData($order['data_entrada']))?></time></article><?php endforeach;?></div></div>
<div class="tab-content" id="tab-changes"><div class="timeline"><?php foreach($events as $event):?><article class="event"><span class="event-icon"><i class="bi bi-clock-history"></i></span><div><strong><?=mobE($event['titulo'])?> <?=$event['resolvido']?'• resolvido':''?></strong><p><?=mobE(trim(($event['valor_anterior']?'Anterior: '.$event['valor_anterior'].' — ':'').($event['valor_novo']?'Novo: '.$event['valor_novo']:'').($event['detalhes']?' • '.$event['detalhes']:'')))?></p></div><time><?=mobE(mobData($event['criado_em']))?></time></article><?php endforeach;?></div></div></section>
</main></div><script>document.querySelectorAll('.tab').forEach(function(button){button.addEventListener('click',function(){document.querySelectorAll('.tab').forEach(function(item){item.classList.remove('primary')});document.querySelectorAll('.tab-content').forEach(function(item){item.classList.remove('active')});button.classList.add('primary');document.getElementById('tab-'+button.dataset.tab).classList.add('active')})});</script></body></html>
