<?php
namespace WorkbloomERP\Module\v0\Auth\Utils;

use KrothiumAPI\Utils\HttpUtil;
use WorkbloomERP\Utils\JwtUtil;
use WorkbloomERP\Utils\CacheUtil;
use WorkbloomERP\Utils\CryptoUtil;
use WorkbloomERP\Module\v0\Usuario\Models\UsuarioModel;
use WorkbloomERP\Module\v0\Auth\Factories\ServiceFactory;
use WorkbloomERP\Module\v0\Usuario\Models\UsuarioSessionModel;

class AuthUtil {
    /**
     * Recupera os dados de uma sessão de "Login Inicial" a partir do cache.
     *
     * Este método é utilizado para verificar se existe uma sessão ativa vinculada ao 
     * token de acesso atual no fluxo de "Primeiro Acesso" (Initial Login). Ele permite 
     * identificar rapidamente se o usuário está em um estado que exige ações 
     * obrigatórias, como a alteração de senha inicial ou configuração de MFA, 
     * sem a necessidade de consultar o banco de dados.
     *
     * ---
     * ## Fluxo de Execução
     * 1. **Identificação:** Extrai o token Bearer da requisição atual (`HttpUtil::getBearerToken()`).
     * 2. **Busca em Cache:** Consulta o serviço de cache (Redis) utilizando a chave prefixada `login:init:{token}`.
     * 3. **Retorno:** Devolve os dados da sessão (array) caso o registro exista e esteja ativo; retorna `null` caso a sessão não exista ou tenha expirado.
     *
     * ---
     * ## Observações Técnicas
     * - **Performance:** Este método é altamente performático por consultar exclusivamente a camada de cache, sendo ideal para middlewares de validação de fluxo de login.
     * - **Segurança:** A chave de busca utiliza o próprio token Bearer, garantindo que o acesso aos dados da sessão inicial seja restrito ao detentor do token correspondente.
     * - **Integração:** Este método deve ser utilizado em conjunto com o fluxo de autenticação que persiste os dados do login inicial no cache.
     *
     * @return array|null Retorna o payload da sessão de login inicial se encontrada; retorna `null` se a sessão não existir no cache.
     */
    public static function readInitSession(): ?array {
        // Verifica se existe um login inicial
        $bearerToken = HttpUtil::getBearerToken();
        $initSession = CacheUtil::get(key: "login:init:{$bearerToken}");
        if ($initSession) {
            return $initSession;
        }
        return null;
    }

    /**
     * Recupera a sessão principal do usuário ou uma chave específica do payload armazenado em cache.
     *
     * Este método centraliza o acesso aos dados de sessão ativos. Ele utiliza o 
     * token Bearer da requisição atual para localizar o payload no cache (Redis) e, 
     * caso uma chave específica seja fornecida, retorna apenas o subconjunto de dados 
     * solicitado, otimizando o acesso às informações de contexto.
     *
     * ---
     * ## Fluxo de Execução
     * 1. **Identificação:** Obtém o token de acesso (Bearer Token) da requisição atual via `HttpUtil`.
     * 2. **Busca:** Consulta o cache usando a chave padronizada `login:main:{token}`.
     * 3. **Filtragem:** 
     *    - Se uma `$key` for fornecida e existir no payload, retorna apenas o valor correspondente (ex: `user_data`).
     *    - Se nenhuma chave for fornecida ou a chave não existir, retorna o payload completo.
     * 4. **Retorno:** Devolve `null` caso a sessão não esteja em cache (sessão inexistente ou expirada).
     *
     * ---
     * ## Observações Técnicas
     * - **Performance:** A consulta ao cache é direta e rápida. O método evita redundância ao permitir filtrar os dados necessários logo na leitura.
     * - **Flexibilidade:** A inclusão do parâmetro `$key` permite que outros serviços solicitem apenas o bloco de dados que precisam (ex: dados da empresa ou do usuário), reduzindo o processamento desnecessário de arrays grandes.
     *
     * @param string $key Chave específica a ser extraída do payload da sessão (opcional; se vazio, retorna o payload completo).
     * @return array|null Retorna o payload da sessão ou um subconjunto dele; retorna `null` se a sessão não existir no cache.
     */
    public static function readSession(string $key): ?array {
        $bearerToken = HttpUtil::getBearerToken();
        $result = CacheUtil::get(key: "login:main:{$bearerToken}");

        if (!$result) {return null;}

        if ($key && isset($result[$key])) {
            return $result[$key];
        }

        return $result;
    }
}