<?php
declare(strict_types=1);
require_once __DIR__.'/common.php';

apiMethod('POST');
apiRateLimit($mysqli, 'register', 8, 900);
$cfg = apiCfg($mysqli);
$payload = apiJson(65536);
$code = strtoupper(apiText($payload['activation_code'] ?? '', 32));
$fingerprint = strtolower(apiText($payload['fingerprint_hash'] ?? '', 64));
if (!preg_match('/^[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}$/', $code)) apiOut(422, ['ok'=>false,'message'=>'Formato do código de ativação inválido.']);
if (!preg_match('/^[a-f0-9]{64}$/', $fingerprint)) apiOut(422, ['ok'=>false,'message'=>'Identificador do dispositivo inválido.']);

$type = strtoupper(apiText($payload['device_type'] ?? 'TABLET', 20));
if (!in_array($type, ['TABLET','SMARTPHONE','OUTRO'], true)) $type = 'OUTRO';
$patrimony = apiText($payload['patrimonio'] ?? '', 60) ?: null;
$responsible = apiText($payload['responsavel_nome'] ?? '', 160) ?: null;
$department = apiText($payload['setor'] ?? '', 180) ?: null;
$serial = apiText($payload['numero_serie_manual'] ?? '', 120) ?: null;
$imei = apiText($payload['imei_manual'] ?? '', 40) ?: null;
$notes = apiText($payload['observacoes'] ?? '', 1000) ?: null;
$androidHash = strtolower(apiText($payload['android_id_hash'] ?? '', 64)) ?: null;
if ($androidHash !== null && !preg_match('/^[a-f0-9]{64}$/', $androidHash)) apiOut(422, ['ok'=>false,'message'=>'Android ID inválido.']);
if ($patrimony === null || $responsible === null || $department === null) apiOut(422, ['ok'=>false,'message'=>'Patrimônio, responsável e setor são obrigatórios.']);

$token = bin2hex(random_bytes(32));
$tokenHash = hash('sha256', $token);
$links = apiLink($mysqli, $patrimony, $imei, $serial);
$smartphoneId = (int)($links['smartphone_id'] ?? 0);
$assetId = (int)($links['asset_id'] ?? 0);
$ip = apiIp();

$mysqli->begin_transaction();
try {
    $stmt = $mysqli->prepare('SELECT enrollment_hash,enrollment_expires_at,enrollment_uses_remaining,sync_interval_min,collect_apps,current_app_version,current_app_version_code FROM ti_mobile_config WHERE id=1 FOR UPDATE');
    $stmt->execute();$enrollment = $stmt->get_result()->fetch_assoc();$stmt->close();
    $validHash = !empty($enrollment['enrollment_hash']) && hash_equals((string)$enrollment['enrollment_hash'], hash('sha256', $code));
    $validTime = !empty($enrollment['enrollment_expires_at']) && strtotime((string)$enrollment['enrollment_expires_at']) >= time();
    $hasUses = (int)($enrollment['enrollment_uses_remaining'] ?? 0) > 0;
    if (!$validHash || !$validTime || !$hasUses) throw new DomainException('Código de ativação inválido, expirado ou já utilizado.');

    $stmt = $mysqli->prepare('SELECT * FROM ti_mobile_dispositivos WHERE fingerprint_hash=? LIMIT 1 FOR UPDATE');
    $stmt->bind_param('s', $fingerprint);$stmt->execute();$existing = $stmt->get_result()->fetch_assoc();$stmt->close();
    if ($existing) {
        $id = (int)$existing['id'];$agent = (string)$existing['agent_id'];
        $stmt = $mysqli->prepare("UPDATE ti_mobile_dispositivos SET token_hash=?,token_emitido_em=NOW(),android_id_hash=?,tipo_dispositivo=?,patrimonio=?,numero_serie_manual=?,imei_manual=?,responsavel_nome=?,setor=?,observacoes=?,vinculo_smartphone_id=NULLIF(?,0),vinculo_ativo_id=NULLIF(?,0),status='ATIVO',revogado_em=NULL,revogado_por=NULL,ultimo_ip_remoto=?,ultima_comunicacao=NOW() WHERE id=?");
        $stmt->bind_param('sssssssssiisi', $tokenHash,$androidHash,$type,$patrimony,$serial,$imei,$responsible,$department,$notes,$smartphoneId,$assetId,$ip,$id);$stmt->execute();$stmt->close();
        apiEvent($mysqli,$id,'REPROVISIONAMENTO','INFO','Agente reprovisionado',null,null,'Novo token emitido após ativação válida.','ATIVACAO');
    } else {
        $stmt = $mysqli->prepare("INSERT INTO ti_mobile_dispositivos(agent_id,token_hash,fingerprint_hash,android_id_hash,tipo_dispositivo,patrimonio,numero_serie_manual,imei_manual,responsavel_nome,setor,observacoes,vinculo_smartphone_id,vinculo_ativo_id,status,ultima_comunicacao,ultimo_ip_remoto) VALUES(NULL,?,?,?,?,?,?,?,?,?,?,NULLIF(?,0),NULLIF(?,0),'ATIVO',NOW(),?)");
        $stmt->bind_param('ssssssssssiis', $tokenHash,$fingerprint,$androidHash,$type,$patrimony,$serial,$imei,$responsible,$department,$notes,$smartphoneId,$assetId,$ip);$stmt->execute();$id=(int)$stmt->insert_id;$stmt->close();
        $prefix = $type === 'SMARTPHONE' ? 'MOB' : 'TAB';
        $agent = $prefix.'-'.date('Y').'-'.str_pad((string)$id,7,'0',STR_PAD_LEFT);
        $stmt=$mysqli->prepare('UPDATE ti_mobile_dispositivos SET agent_id=? WHERE id=?');$stmt->bind_param('si',$agent,$id);$stmt->execute();$stmt->close();
        apiEvent($mysqli,$id,'REGISTRO','INFO','Novo dispositivo registrado',null,$agent,'Agente ativado pela primeira vez.','ATIVACAO');
    }
    $stmt=$mysqli->prepare('UPDATE ti_mobile_config SET enrollment_uses_remaining=enrollment_uses_remaining-1 WHERE id=1 AND enrollment_uses_remaining>0');$stmt->execute();$stmt->close();
    apiAudit($mysqli, $existing ? 'REPROVISIONAMENTO' : 'ATIVACAO', $id, $agent, 'Token individual emitido; segredo omitido do log.');
    $mysqli->commit();
    apiOut(200, [
        'ok'=>true,'agent_id'=>$agent,'token'=>$token,
        'sync_interval_min'=>(int)($enrollment['sync_interval_min']??30),
        'collect_apps'=>(bool)($enrollment['collect_apps']??1),
        'current_app_version'=>(string)($enrollment['current_app_version']??'1.0.0'),
        'current_app_version_code'=>(int)($enrollment['current_app_version_code']??1),
        'tracked_apps'=>apiTrackedApps($mysqli)
    ]);
} catch (DomainException $e) {
    $mysqli->rollback();apiAudit($mysqli,'ATIVACAO_NEGADA',null,null,$e->getMessage());apiOut(403,['ok'=>false,'message'=>$e->getMessage()]);
} catch (Throwable) {
    $mysqli->rollback();apiOut(500,['ok'=>false,'message'=>'Não foi possível registrar o dispositivo.']);
}
?>
