<?php
/**
 * AURA FARMING — Etapa 14
 * Idade, classificação da conta e bloqueio preventivo de recursos sensíveis.
 */

function afCalcularIdade(string $dataNascimento, ?DateTimeImmutable $referencia = null): int
{
    $nascimento = DateTimeImmutable::createFromFormat('!Y-m-d', $dataNascimento);
    $erros = DateTimeImmutable::getLastErrors();
    if (!$nascimento || (is_array($erros) && ($erros['warning_count'] > 0 || $erros['error_count'] > 0))) {
        throw new InvalidArgumentException('Informe uma data de nascimento válida.');
    }
    $hoje = $referencia ?: new DateTimeImmutable('today', new DateTimeZone(APP_TIMEZONE));
    if ($nascimento > $hoje) throw new InvalidArgumentException('A data de nascimento não pode estar no futuro.');
    $idade = $nascimento->diff($hoje)->y;
    if ($idade < 0 || $idade > 120) throw new InvalidArgumentException('A data de nascimento informada não é válida.');
    return $idade;
}

function afValidarDeclaracaoIdade(string $dataNascimento, string $pais, string $usoConta): array
{
    $dataNascimento = trim($dataNascimento);
    $pais = trim(strip_tags($pais));
    $usoConta = strtolower(trim($usoConta));
    if (!in_array($usoConta, ['player','guardian'], true)) $usoConta = 'player';
    if (strlen($pais) < 2 || strlen($pais) > 120) throw new InvalidArgumentException('Informe o país de residência.');
    $idade = afCalcularIdade($dataNascimento);
    if ($usoConta === 'guardian' && $idade < 18) {
        throw new InvalidArgumentException('A conta de responsável legal deve pertencer a uma pessoa maior de 18 anos.');
    }
    $tipoConta = $usoConta === 'guardian' ? 'guardian' : ($idade >= 18 ? 'adult' : 'minor');
    $status = $tipoConta === 'guardian' ? 'guardian_declared' : ($idade >= 18 ? 'adult_declared' : 'minor_pending_guardian');
    return [
        'data_nascimento' => $dataNascimento,
        'pais_residencia' => substr($pais, 0, 80),
        'uso_conta' => $usoConta,
        'tipo_conta' => $tipoConta,
        'status_idade' => $status,
        'idade' => $idade,
    ];
}

function afBuscarPerfilIdade(PDO $pdo, int $usuarioId): ?array
{
    try {
        $st = $pdo->prepare('SELECT * FROM af_user_age_profiles WHERE usuario_id=? LIMIT 1');
        $st->execute([$usuarioId]);
        return $st->fetch() ?: null;
    } catch (Throwable $e) {
        if (defined('APP_DEBUG') && APP_DEBUG) error_log('[AURA-AGE] '.$e->getMessage());
        return null;
    }
}

function afResumoIdade(PDO $pdo, int $usuarioId): array
{
    $perfil = afBuscarPerfilIdade($pdo, $usuarioId);
    if (!$perfil) {
        return [
            'completo' => false,
            'status' => 'unverified',
            'tipo_conta' => 'unknown',
            'idade' => null,
            'data_nascimento' => null,
            'pais_residencia' => null,
            'pode_recursos_sensiveis' => false,
            'rotulo' => 'Idade não confirmada',
            'mensagem' => 'Confirme sua data de nascimento para continuar usando o Aura Farming.',
        ];
    }
    $status = (string)$perfil['status_idade'];
    $idade = isset($perfil['idade_declarada']) ? (int)$perfil['idade_declarada'] : null;
    $permitido = in_array($status, ['adult_verified','guardian_verified'], true);
    if (!$permitido && in_array($status,['adult_declared','guardian_declared'],true) && function_exists('afAgeAssuranceStatus')) {
        $permitido = !empty(afAgeAssuranceStatus($pdo,$usuarioId)['ready']);
    }
    $rotulo = match ($status) {
        'adult_verified' => 'Conta adulta confirmada',
        'adult_declared' => 'Maioridade declarada — confirmação pendente',
        'guardian_declared' => 'Responsável declarado — revisão pendente',
        'guardian_verified' => 'Responsável maior de idade',
        'minor_pending_guardian' => 'Aguardando autorização do responsável',
        'minor_authorized' => 'Menor autorizado — proteções pendentes',
        'blocked' => 'Conta bloqueada por idade',
        default => 'Idade não confirmada',
    };
    $mensagem = match ($status) {
        'adult_verified' => 'Sua classificação etária foi concluída pelo fluxo interno.',
        'adult_declared' => 'Confirme o e-mail da conta para liberar câmera e recursos sociais.',
        'guardian_declared' => 'Conclua a verificação interna do responsável antes de autorizar um menor.',
        'guardian_verified' => 'Sua conta está classificada como responsável maior de idade.',
        'minor_pending_guardian' => 'Solicite o vínculo de um responsável. Câmera e recursos sociais continuam bloqueados.',
        'minor_authorized' => 'O motor de políticas da Etapa 18 está ativo. Cada recurso é avaliado separadamente; câmera e Farm aguardam a câmera segura da Etapa 19.',
        'blocked' => 'Esta conta não pode utilizar recursos sensíveis.',
        default => 'Confirme sua data de nascimento para continuar.',
    };
    $guardian = null;
    $consent = null;
    if ((string)$perfil['tipo_conta'] === 'minor' && function_exists('afGuardianResumoDoMenor')) {
        try { $guardian = afGuardianResumoDoMenor($pdo,$usuarioId); } catch (Throwable $e) { $guardian = null; }
        if (function_exists('afConsentResumoDoMenor')) {
            try { $consent = afConsentResumoDoMenor($pdo,$usuarioId); } catch (Throwable $e) { $consent = null; }
        }
        if (!empty($consent['active'])) {
            $rotulo = 'Consentimentos parentais registrados';
            $mensagem = 'O responsável definiu as autorizações. O motor de políticas avalia cada recurso; câmera e Farm aguardam a câmera segura da Etapa 19.';
        } elseif (!empty($guardian['vinculado'])) {
            if (($guardian['etapa'] ?? '') === 'guardian_verified_pending_consent') {
                $rotulo = 'Responsável adulto verificado';
                $mensagem = 'O responsável concluiu a verificação. Agora precisa registrar os consentimentos específicos.';
            } else {
                $rotulo = 'Responsável vinculado';
                $mensagem = 'O vínculo foi criado. A verificação do adulto ainda precisa ser concluída antes dos consentimentos.';
            }
        } elseif (!empty($guardian['convite_pendente'])) {
            $rotulo = 'Convite enviado ao responsável';
            $mensagem = 'Aguardando o responsável abrir o link e aceitar o vínculo. Os recursos sensíveis continuam bloqueados.';
        }
    }
    return [
        'completo' => true,
        'status' => $status,
        'tipo_conta' => (string)$perfil['tipo_conta'],
        'idade' => $idade,
        'data_nascimento' => (string)$perfil['data_nascimento'],
        'pais_residencia' => (string)$perfil['pais_residencia'],
        'pode_recursos_sensiveis' => $permitido,
        'rotulo' => $rotulo,
        'mensagem' => $mensagem,
        'guardian' => $guardian,
        'consent' => $consent,
    ];
}

function afRegistrarDeclaracaoIdade(
    PDO $pdo,
    int $usuarioId,
    string $dataNascimento,
    string $pais,
    string $usoConta = 'player',
    string $origem = 'web',
    bool $permitirAlteracao = false
): array {
    $dados = afValidarDeclaracaoIdade($dataNascimento, $pais, $usoConta);
    $anterior = afBuscarPerfilIdade($pdo, $usuarioId);
    if ($anterior && !$permitirAlteracao && (string)$anterior['status_idade'] !== 'unverified') {
        throw new RuntimeException('Sua idade já foi confirmada. Alterações precisam ser analisadas pela equipe de segurança.');
    }

    $statusAnterior = $anterior['status_idade'] ?? 'unverified';
    $sql = 'INSERT INTO af_user_age_profiles
        (usuario_id,data_nascimento,pais_residencia,tipo_conta,status_idade,idade_declarada,origem_declaracao,declarado_em,verificado_em,atualizado_em)
        VALUES (?,?,?,?,?,?,?,NOW(),NULL,NOW())
        ON DUPLICATE KEY UPDATE data_nascimento=VALUES(data_nascimento),pais_residencia=VALUES(pais_residencia),
        tipo_conta=VALUES(tipo_conta),status_idade=VALUES(status_idade),idade_declarada=VALUES(idade_declarada),
        origem_declaracao=VALUES(origem_declaracao),declarado_em=NOW(),verificado_em=NULL,atualizado_em=NOW()';
    $pdo->prepare($sql)->execute([
        $usuarioId,$dados['data_nascimento'],$dados['pais_residencia'],$dados['tipo_conta'],
        $dados['status_idade'],$dados['idade'],$origem
    ]);

    $pdo->prepare('INSERT INTO af_age_verifications
        (usuario_id,metodo,resultado,data_nascimento,pais_residencia,idade_calculada,ip_address,user_agent,device_uuid,criado_em)
        VALUES (?,?,?,?,?,?,?,?,?,NOW())')->execute([
        $usuarioId,'self_declaration',$dados['idade'] >= 18 ? 'adult_declared' : 'minor',
        $dados['data_nascimento'],$dados['pais_residencia'],$dados['idade'],clientIp(),
        substr((string)($_SERVER['HTTP_USER_AGENT'] ?? ''),0,1000),deviceUuid()
    ]);

    $pdo->prepare('INSERT INTO af_age_status_history
        (usuario_id,status_anterior,status_novo,motivo,actor_usuario_id,dados,criado_em)
        VALUES (?,?,?,?,NULL,?,NOW())')->execute([
        $usuarioId,$statusAnterior,$dados['status_idade'],'declaração de idade',
        json_encode(['origem'=>$origem,'tipo_conta'=>$dados['tipo_conta'],'idade'=>$dados['idade']], JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES)
    ]);

    if ($dados['status_idade'] === 'minor_pending_guardian') {
        $pdo->prepare('UPDATE af_perfis SET perfil_privado=1,atualizado_em=NOW() WHERE usuario_id=?')->execute([$usuarioId]);
        criarNotificacao($pdo,$usuarioId,'age_restriction','Conta protegida por idade','Recursos de câmera, Farm, Battle, transmissão e compartilhamento foram bloqueados. Agora você pode convidar um responsável para criar o vínculo inicial.');
    } elseif ($dados['status_idade'] === 'adult_declared') {
        criarNotificacao($pdo,$usuarioId,'age_assurance_required','Confirmação de maioridade pendente','Confirme o e-mail da conta para liberar câmera e recursos sociais.');
    } else {
        criarNotificacao($pdo,$usuarioId,'guardian_review_required','Verificação do responsável pendente','Conclua o fluxo interno de verificação antes de autorizar um menor.');
    }
    return $dados;
}

function afFeatureLabel(string $feature): string
{
    $feature = function_exists('afMinorPolicyFeatureAlias') ? afMinorPolicyFeatureAlias($feature) : $feature;
    return match ($feature) {
        'farm' => 'Farm e câmera',
        'camera' => 'Câmera e detecção de movimentos',
        'body_processing' => 'Processamento corporal',
        'battle' => 'Aura Battle',
        'competition' => 'Competições',
        'live', 'public_live' => 'Transmissões ao vivo',
        'share' => 'Compartilhamentos',
        'challenge' => 'Desafios',
        'ranking_alias' => 'Ranking protegido',
        'social_follow' => 'Interações sociais',
        'full_public_profile' => 'Perfil público completo',
        default => 'Este recurso',
    };
}

function afCanUseAgeFeature(PDO $pdo, int $usuarioId, string $feature): bool
{
    if (function_exists('afMinorPolicyDecision')) {
        return !empty(afMinorPolicyDecision($pdo,$usuarioId,$feature,[],false)['allowed']);
    }
    $resumo = afResumoIdade($pdo, $usuarioId);
    if (!$resumo['completo']) return false;
    return in_array($resumo['status'], ['adult_verified','guardian_verified'], true);
}

function afCanPublishUserContent(PDO $pdo, int $usuarioId): bool
{
    if (function_exists('afMinorPolicyCanExposePublicContent')) {
        return afMinorPolicyCanExposePublicContent($pdo,$usuarioId,'full_public_profile');
    }
    return afCanUseAgeFeature($pdo, $usuarioId, 'share');
}

function afAgeRestrictionUrl(string $feature): string
{
    return SITE_URL.'/pages/restricao-idade.php?feature='.rawurlencode($feature);
}

function afRequireAgeFeature(PDO $pdo, string $feature, array $context = []): void
{
    $uid = (int)($_SESSION['usuario_id'] ?? 0);
    if ($uid <= 0) {
        header('Location: '.SITE_URL.'/auth/login.php'); exit;
    }
    $resumo = afResumoIdade($pdo, $uid);
    if (!$resumo['completo']) {
        $_SESSION['af_after_age'] = (string)($_SERVER['REQUEST_URI'] ?? '/pages/home.php');
        setFlash('error','Confirme sua data de nascimento antes de usar '.afFeatureLabel($feature).'.');
        header('Location: '.SITE_URL.'/pages/verificar-idade.php'); exit;
    }
    if (function_exists('afMinorPolicyRequire')) {
        afMinorPolicyRequire($pdo,$feature,$context);
        return;
    }
    if (!afCanUseAgeFeature($pdo, $uid, $feature)) {
        header('Location: '.afAgeRestrictionUrl($feature)); exit;
    }
}

function afEnforceAgeCompletion(PDO $pdo, int $usuarioId): void
{
    $script = str_replace('\\','/',(string)($_SERVER['SCRIPT_NAME'] ?? ''));
    $permitidos = [
        '/pages/verificar-idade.php',
        '/pages/verificar-maioridade.php',
        '/pages/restricao-idade.php',
        '/pages/seguranca-menor.php',
        '/pages/responsavel.php',
        '/pages/painel-responsavel.php',
        '/pages/verificar-responsavel.php',
        '/pages/consentimentos-responsavel.php',
        '/pages/dependente-responsavel.php',
        '/pages/alertas-responsavel.php',
        '/pages/central-privacidade.php',
        '/pages/exportar-dados.php',
        '/pages/convite-responsavel.php',
        '/auth/logout.php',
    ];
    foreach ($permitidos as $permitido) {
        if (str_ends_with($script, $permitido)) return;
    }
    $resumo = afResumoIdade($pdo, $usuarioId);
    if (!$resumo['completo']) {
        $uri = (string)($_SERVER['REQUEST_URI'] ?? '/pages/home.php');
        if (str_starts_with($uri,'/') && !str_starts_with($uri,'//')) $_SESSION['af_after_age']=$uri;
        setFlash('error','Antes de continuar, confirme sua data de nascimento.');
        header('Location: '.SITE_URL.'/pages/verificar-idade.php'); exit;
    }
}

function afSensitiveFeatureForApiScript(): ?string
{
    $path = str_replace('\\','/',(string)($_SERVER['SCRIPT_NAME'] ?? ''));
    $base = basename($path);
    if (str_contains($path,'/api/v1/battles/')) return 'battle';
    if (str_contains($path,'/api/v1/competitions/')) return 'competition';
    if (str_contains($path,'/api/v1/live/')) return 'public_live';
    if (str_contains($path,'/api/v1/viral/')) return 'share';
    if (str_contains($path,'/api/v1/social/follow.php')) return 'social_follow';
    if (str_contains($path,'/api/v1/matches/')) {
        if ($base === 'share.php') return 'share';
        if (in_array($base,['start.php','begin.php','heartbeat.php','finish.php','cancel.php','active.php'],true)) return 'farm';
    }
    return null;
}

function afAssertApiAgeAccess(PDO $pdo, array $usuario, ?string $feature = null, array $context = []): void
{
    $uid = (int)($usuario['id'] ?? 0);
    if ($uid <= 0) jsonResponse(['ok'=>false,'erro'=>'Usuário inválido.'],401);
    $resumo = afResumoIdade($pdo,$uid);
    if (!$resumo['completo']) {
        jsonResponse(['ok'=>false,'code'=>'AGE_VERIFICATION_REQUIRED','erro'=>'Confirme sua data de nascimento antes de usar este recurso.','age'=>$resumo],403);
    }
    if ($feature === null || $feature === '') return;
    if (function_exists('afMinorPolicyApiAssert')) {
        afMinorPolicyApiAssert($pdo,$usuario,$feature,$context);
        return;
    }
    if (!afCanUseAgeFeature($pdo,$uid,$feature)) {
        jsonResponse(['ok'=>false,'code'=>'PARENTAL_AUTHORIZATION_REQUIRED','erro'=>afFeatureLabel($feature).' está bloqueado para esta conta.','age'=>$resumo],403);
    }
}
