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

use KrothiumAPI\Utils\HttpUtil;
use WorkbloomERP\Utils\SanitizeUtil;
use WorkbloomERP\Exceptions\AppException;
use WorkbloomERP\Module\v0\Auth\Factories\ServiceFactory;

class AuthController {
    /**
     * Endpoint de API para autenticação de usuário (**Login**).
     *
     * Este método gerencia a interface HTTP (POST) para validar as credenciais do usuário.
     * Ele atua como uma camada fina (*Thin Controller*), responsável por capturar o 
     * payload da requisição, sanitizar os dados de entrada para prevenir injeções 
     * e delegar a verificação de identidade e gestão de sessão/tokens para o `AuthService`.
     *
     * ---
     * ## Fluxo de Execução
     * 1. **Captura e Validação:** Extrai o corpo da requisição. Se o payload estiver vazio, interrompe com erro 400 (Bad Request).
     * 2. **Sanitização:** Aplica `SanitizeUtil::string()` nos campos de login e senha para garantir a limpeza dos dados antes do processamento de negócio.
     * 3. **Processamento de Negócio:** Invoca `AuthService::login()`, que realiza a consulta de credenciais.
     * 4. **Normalização de Resposta:**
     *    - **Sucesso (200 OK):** Retorna os dados de sessão (ex: token de acesso).
     *    - **Tratamento de Erros:** Captura `AppException` (credenciais inválidas, conta bloqueada, etc.), formatando a resposta para que o frontend receba um objeto de erro estruturado.
     *
     * ---
     * ## Observações Técnicas
     * - A responsabilidade de verificar a hash da senha e gerar o token de acesso reside exclusivamente no `AuthService`, isolando a lógica de segurança do controlador.
     * - Utiliza `HttpUtil` para garantir consistência no formato da resposta JSON, independentemente do sucesso ou falha da autenticação.
     *
     * @return void O método encerra o processamento enviando uma resposta HTTP JSON ao cliente.
     * @see AuthService::login() Para os detalhes sobre a regra de autenticação e geração de tokens.
     */
    public function login(): void {
        try {
            $form = HttpUtil::getRequestBody(form_type: 'POST');
            if (empty($form)) {
                throw new AppException(message: 'Requisição inválida.', code: 400);
            }

            $authService = ServiceFactory::makeAuthService();
            $response = $authService->login(login: SanitizeUtil::string(value: $form['login']), senha: SanitizeUtil::string(value: $form['senha']));

            HttpUtil::jsonResponse(
                response_code: $response['response_code'] ?? 200,
                message: $response['message'] ?? 'Login realizado com sucesso.',
                output: $response['output'] ?? null
            );
        } catch(AppException $e) {
            HttpUtil::jsonResponse(
                response_code: $e->getCode() ?? 500,
                message: $e->getMessage(),
                output: $e->getDetails() ? ['errors' => $e->getDetails()] : null
            );
        }
    }

    /**
     * Endpoint de API para a seleção de contexto de empresa ativa.
     *
     * Este método gerencia a interface HTTP (POST) para permitir que um usuário 
     * autenticado alterne sua empresa ativa no sistema multi-empresa. O controlador 
     * realiza a captura do payload, sanitiza o UUID da empresa e delega a 
     * complexa lógica de troca de sessão e regeneração de tokens ao `AuthService`.
     *
     * ---
     * ## Fluxo de Execução
     * 1. **Captura e Validação:** Extrai o corpo da requisição. Se o payload estiver vazio ou malformado, retorna erro 400 (Bad Request).
     * 2. **Sanitização:** Aplica `SanitizeUtil::string()` no `empresa_uuid` para garantir a integridade dos dados recebidos.
     * 3. **Processamento de Negócio:** Invoca `AuthService::selectCompany()`, que valida o acesso à empresa, gera um novo JWT e registra a sessão.
     * 4. **Normalização de Resposta:**
     *    - **Sucesso (200 OK):** Retorna o novo token de acesso contendo o contexto da empresa selecionada.
     *    - **Tratamento de Erros:** Captura `AppException` (ex: empresa inexistente, falta de permissão), retornando uma resposta JSON estruturada com os detalhes do erro para o cliente.
     *
     * ---
     * ## Arquitetura de Seleção de Contexto
     * 
     *
     * ---
     * ## Observações Técnicas
     * - Segue o padrão "Thin Controller", onde a orquestração de infraestrutura (cache, banco de dados, JWT) é encapsulada na camada de serviço.
     * - Este endpoint é fundamental para aplicações multi-tenant ou multi-empresa, permitindo que o usuário altere seu "escopo" de atuação sem precisar realizar um re-login completo.
     *
     * @return void O método encerra o processamento enviando uma resposta HTTP JSON ao cliente.
     * @see AuthService::selectCompany() Para os detalhes sobre a regra de negócio aplicada na troca de contexto.
     */
    public function selectCompany(): void {
        try {
            $form = HttpUtil::getRequestBody(form_type: 'POST');
            if (empty($form)) {
                throw new AppException(message: 'Requisição inválida.', code: 400);
            }

            $authService = ServiceFactory::makeAuthService();
            $response = $authService->selectCompany(empresa_uuid: SanitizeUtil::string(value: $form['empresa_uuid']));

            HttpUtil::jsonResponse(
                response_code: $response['response_code'] ?? 200,
                message: $response['message'] ?? 'Empresa selecionada com sucesso.',
                output: $response['output'] ?? null
            );
        } catch(AppException $e) {
            HttpUtil::jsonResponse(
                response_code: $e->getCode() ?? 500,
                message: $e->getMessage(),
                output: $e->getDetails() ? ['errors' => $e->getDetails()] : null
            );
        }
    }
}