<?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(!mobEhRenan()){http_response_code(403);exit('Somente Renan pode executar o instalador inicial.');}$mysqli->set_charset('utf8mb4');$csrf=mobCsrf();$ok=[];$erro='';$codigo=null;
function mobRunSql(mysqli $db,string $file): void {$sql=file_get_contents($file);if($sql===false)throw new RuntimeException('Arquivo SQL não encontrado.');$sql=preg_replace('/^\s*--.*$/m','',$sql)??$sql;foreach(array_filter(array_map('trim',preg_split('/;\s*(?:\r?\n|$)/',$sql)?:[])) as $cmd){if($cmd!==''&&!$db->query($cmd))throw new RuntimeException('Erro SQL: '.$db->error);}}
function mobEnsureColumn(mysqli $db,string $table,string $column,string $definition): void {$stmt=$db->prepare('SELECT COUNT(*) total FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name=? AND column_name=?');$stmt->bind_param('ss',$table,$column);$stmt->execute();$exists=(int)($stmt->get_result()->fetch_assoc()['total']??0)>0;$stmt->close();if(!$exists&&!$db->query("ALTER TABLE `{$table}` ADD COLUMN `{$column}` {$definition}"))throw new RuntimeException("Falha ao atualizar {$table}.{$column}: ".$db->error);}
function mobMigrateExisting(mysqli $db): void {
    $columns=[
      'ti_mobile_config'=>['enrollment_expires_at'=>'DATETIME NULL AFTER enrollment_hash','enrollment_uses_remaining'=>'SMALLINT UNSIGNED NOT NULL DEFAULT 0 AFTER enrollment_expires_at','recent_hours'=>'SMALLINT UNSIGNED NOT NULL DEFAULT 2 AFTER sync_interval_min','silent_hours'=>'SMALLINT UNSIGNED NOT NULL DEFAULT 24 AFTER recent_hours','security_patch_max_age_days'=>'SMALLINT UNSIGNED NOT NULL DEFAULT 365 AFTER storage_critical_percent','min_android_sdk'=>'SMALLINT UNSIGNED NOT NULL DEFAULT 29 AFTER security_patch_max_age_days','current_app_version'=>"VARCHAR(40) NOT NULL DEFAULT '1.0.0' AFTER min_android_sdk",'current_app_version_code'=>'INT UNSIGNED NOT NULL DEFAULT 1 AFTER current_app_version'],
      'ti_mobile_dispositivos'=>['token_emitido_em'=>'DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER token_hash','armazenamento_usado_mb'=>'BIGINT UNSIGNED NULL AFTER armazenamento_total_mb','bateria_carregando'=>'TINYINT(1) NULL AFTER bateria_percentual','app_version_code'=>'INT UNSIGNED NULL AFTER app_version','vinculo_ativo_id'=>'BIGINT UNSIGNED NULL AFTER vinculo_smartphone_id','revogado_em'=>'DATETIME NULL AFTER status','revogado_por'=>'VARCHAR(120) NULL AFTER revogado_em'],
      'ti_mobile_sincronizacoes'=>['app_version_code'=>'INT UNSIGNED NULL AFTER app_version'],
      'ti_mobile_eventos'=>['origem'=>"VARCHAR(40) NOT NULL DEFAULT 'AGENTE' AFTER detalhes",'status_revisao'=>"ENUM('ABERTO','RECONHECIDO','RESOLVIDO') NOT NULL DEFAULT 'ABERTO' AFTER origem",'reconhecido_por'=>'VARCHAR(120) NULL AFTER status_revisao','reconhecido_em'=>'DATETIME NULL AFTER reconhecido_por','observacao_revisao'=>'TEXT NULL AFTER reconhecido_em'],
      'ti_mobile_apps'=>['instalado'=>'TINYINT(1) NOT NULL DEFAULT 1 AFTER version_code','obrigatorio'=>'TINYINT(1) NOT NULL DEFAULT 0 AFTER instalado']
    ];foreach($columns as $table=>$items)foreach($items as $column=>$definition)mobEnsureColumn($db,$table,$column,$definition);
}
if($_SERVER['REQUEST_METHOD']==='POST')try{mobCheckCsrf();mobRunSql($mysqli,__DIR__.'/SQL_INVENTARIO_MOBILE.sql');mobMigrateExisting($mysqli);$ok[]='Banco, índices e migrações do inventário Android criados ou confirmados.';$codigo=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',$codigo);$u=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,$u);$stmt->execute();$stmt->close();$ok[]='Código inicial de ativação criado, válido por 24 horas e para um uso.';if(mobTableExists($mysqli,'ti_modulos')){$stmt=$mysqli->prepare("INSERT INTO ti_modulos(slug,nome,descricao,icone,ordem,ativo) VALUES('inventario_mobile','Tablets Android','Inventário automatizado de tablets e smartphones Android','bi-tablet-fill',105,1) ON DUPLICATE KEY UPDATE nome=VALUES(nome),descricao=VALUES(descricao),icone=VALUES(icone),ordem=VALUES(ordem),ativo=1");$stmt->execute();$stmt->close();$ok[]='Módulo adicionado à Matriz de Permissões.';}if(mobTableExists($mysqli,'ti_usuario_permissoes')&&mobTableExists($mysqli,'usuarios')){$r=$mysqli->query("SELECT id,usuario FROM usuarios");while($r&&$x=$r->fetch_assoc()){if(mobNorm((string)$x['usuario'])!=='renan')continue;$uid=(int)$x['id'];$slug='inventario_mobile';$stmt=$mysqli->prepare("INSERT INTO ti_usuario_permissoes(user_id,modulo_slug,pode_visualizar,pode_cadastrar,pode_editar,pode_excluir,pode_transferir,pode_finalizar,pode_exportar,pode_administrar,atualizado_por) VALUES(?,?,1,1,1,1,1,1,1,1,?) ON DUPLICATE KEY UPDATE pode_visualizar=1,pode_cadastrar=1,pode_editar=1,pode_excluir=1,pode_transferir=1,pode_finalizar=1,pode_exportar=1,pode_administrar=1,atualizado_por=VALUES(atualizado_por)");$stmt->bind_param('iss',$uid,$slug,$u);$stmt->execute();$stmt->close();}$ok[]='Renan recebeu acesso total. Cynthia não recebeu acesso ao novo módulo.';}if(!is_dir(__DIR__.'/downloads')&&!mkdir(__DIR__.'/downloads',0775,true))throw new RuntimeException('Não foi possível preparar downloads/.');if(!is_writable(__DIR__.'/downloads'))$ok[]='Aviso: downloads/ existe, mas não está gravável pelo PHP.';else $ok[]='Diretório downloads/ pronto para publicar o APK.';$ok[]='Requisitos: PHP '.PHP_VERSION.', MySQL conectado, random_bytes e JSON disponíveis.';$ok[]='Estrutura pronta. Apague este instalador depois de concluir.';}catch(Throwable $e){$erro=$e->getMessage();}
?><!doctype html><html lang="pt-BR"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Instalar Inventário Android</title><style>body{margin:0;min-height:100vh;display:grid;place-items:center;padding:20px;font-family:Arial,sans-serif;color:#172438;background:#edf3f8}.box{width:min(760px,100%);overflow:hidden;border-radius:26px;background:#fff;box-shadow:0 30px 90px rgba(8,57,111,.18)}header{padding:24px;color:#fff;background:linear-gradient(145deg,#061f42,#0b4d91)}main{padding:24px}.ok,.err,.code{margin:10px 0;padding:12px;border-radius:13px}.ok{color:#076448;background:#e8f8f1}.err{color:#922138;background:#fff0f3}.code{color:#fff;background:#0b4d91}.code strong{font-size:22px;letter-spacing:2px}button,a{min-height:44px;display:inline-flex;align-items:center;padding:0 15px;border:0;border-radius:12px;color:#fff;background:#0b4d91;text-decoration:none;font-weight:bold;cursor:pointer}</style></head><body><section class="box"><header><h1>Inventário Android</h1><p>Tablets e smartphones institucionais.</p></header><main><?php if($erro):?><div class="err"><?=mobE($erro)?></div><?php endif;?><?php foreach($ok as $m):?><div class="ok"><?=mobE($m)?></div><?php endforeach;?><?php if($codigo):?><div class="code">Código inicial de ativação:<br><strong><?=mobE($codigo)?></strong><br><small>Copie agora. Depois o sistema guarda somente o hash.</small></div><a href="inventario_equipamentos.php">Abrir Inventário Android</a><?php else:?><p>Este instalador cria somente as novas tabelas de inventário móvel e integra o módulo à matriz de permissões existente.</p><form method="post"><input type="hidden" name="csrf_token" value="<?=mobE($csrf)?>"><button>INSTALAR MÓDULO</button></form><?php endif;?></main></section></body></html>
