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

use KrothiumAPI\Utils\HttpUtil;
use WorkbloomERP\Utils\SanitizeUtil;
use WorkbloomERP\Exceptions\AppException;
use WorkbloomERP\Module\v0\Contato\DTOs\ContatoCreateDTO;
use WorkbloomERP\Module\v0\Contato\Factories\ContatoServiceFactory;

class ContatoController {
    public function createOptions(): void {
        try {
            $contatoService = ContatoServiceFactory::makeContatoService();
            $options = $contatoService->createOptions();

            HttpUtil::jsonResponse(
                response_code: 200,
                message: 'Opções para criação de contato.',
                output: ['options' => $options]
            );
        } catch (AppException $e) {
            HttpUtil::jsonResponse(
                response_code: $e->getCode() ?? 500,
                message: $e->getMessage() ?? 'Ocorreu um erro ao obter as opções de contato.',
                output: $e->getDetails() ? ['errors' => $e->getDetails()] : null
            );
        }
    }
    /**
     * Endpoint de API para a criação de um novo **Contato**.
     *
     * Este controlador atua como o ponto de entrada para o registro de novos contatos 
     * (parceiros de negócio, fornecedores ou clientes) no sistema. O método é 
     * responsável por extrair os dados da requisição HTTP (POST), aplicar a sanitização 
     * necessária para garantir a integridade dos dados e delegar a criação à camada de 
     * serviço utilizando um `ContatoCreateDTO`.
     *
     * ---
     * ## Fluxo de Execução
     * 1. **Captura e Validação:** Obtém o corpo da requisição (JSON/Form). Valida a presença de dados, retornando erro 422 caso esteja vazio.
     * 2. **Normalização (DTO):** Instancia um `ContatoCreateDTO` populando-o com os dados sanitizados através de `SanitizeUtil`.
     * 3. **Orquestração de Serviço:** Invoca `ContatoService::create()` para validar regras de negócio, persistência e possíveis integrações.
     * 4. **Resposta:** Retorna um JSON estruturado com o status da operação (201 para sucesso ou status de erro correspondente).
     *
     * ---
     * ## Observações Técnicas
     * - O controlador segue o padrão de "Thin Controller", garantindo que as regras de validação complexas e a persistência de dados ocorram na camada de serviço.
     * - Todos os campos de entrada são submetidos a métodos de `SanitizeUtil` para prevenir injeções e garantir o tipo esperado antes de atingir o DTO.
     * - Utiliza `ContatoServiceFactory` para a injeção de dependência do serviço.
     *
     * @return void O método encerra o processamento enviando uma resposta HTTP JSON ao cliente.
     * @see ContatoCreateDTO Para a estrutura de dados esperada para a criação.
     * @see ContatoService::create() Para a lógica de negócio de persistência do contato.
     */
    public function create(): void {
        try {
            $form = HttpUtil::getRequestBody(form_type: 'POST');
            if (empty($form)) {
                throw new AppException(message: 'Requisição inválida.', code: 422);
            }

            $contaoService = ContatoServiceFactory::makeContatoService();
            $response = $contaoService->create(
                contatoCreateDTO: new ContatoCreateDTO(
                    is_active: SanitizeUtil::boolean(value: $form['is_active'] ?? null),
                    tipo: SanitizeUtil::string(value: $form['tipo'] ?? null),
                    nome_empresarial: SanitizeUtil::string(value: $form['nome_empresarial'] ?? null),
                    nome_fantasia: SanitizeUtil::string(value: $form['nome_fantasia'] ?? null),
                    personalidade: SanitizeUtil::string(value: $form['personalidade'] ?? null),
                    document_cpf: SanitizeUtil::string(value: $form['document_cpf'] ?? null),
                    document_cnpj: SanitizeUtil::string(value: $form['document_cnpj'] ?? null),
                    regime_tributario: SanitizeUtil::int(value: $form['regime_tributario'] ?? null),
                    contribuinte_icms: SanitizeUtil::int(value: $form['contribuinte_icms'] ?? null),
                    orgao_publico: SanitizeUtil::string(value: $form['orgao_publico'] ?? null),
                    document_ie: SanitizeUtil::string(value: $form['document_ie'] ?? null),
                    document_im: SanitizeUtil::string(value: $form['document_im'] ?? null),
                    document_is: SanitizeUtil::string(value: $form['document_is'] ?? null),
                    end_cep: SanitizeUtil::string(value: $form['end_cep'] ?? null),
                    end_ibge: SanitizeUtil::string(value: $form['end_ibge'] ?? null),
                    end_logradouro: SanitizeUtil::string(value: $form['end_logradouro'] ?? null),
                    end_numero: SanitizeUtil::string(value: $form['end_numero'] ?? null),
                    end_complemento: SanitizeUtil::string(value: $form['end_complemento'] ?? null),
                    end_bairro: SanitizeUtil::string(value: $form['end_bairro'] ?? null),
                    end_cidade: SanitizeUtil::string(value: $form['end_cidade'] ?? null),
                    end_uf: SanitizeUtil::string(value: $form['end_uf'] ?? null),
                    info_email: SanitizeUtil::string(value: $form['info_email'] ?? null),
                    info_email_nfe: SanitizeUtil::string(value: $form['info_email_nfe'] ?? null),
                    info_observacao: SanitizeUtil::string(value: $form['info_observacao'] ?? null),
                    info_telefone: SanitizeUtil::string(value: $form['info_telefone'] ?? null),
                    info_uso_consumo_ibs_cbs: SanitizeUtil::string(value: $form['info_uso_consumo_ibs_cbs'] ?? null),
                )
            );

            HttpUtil::jsonResponse(
                response_code: $response['response_code'] ?? 201,
                message: $response['message'] ?? 'Contato criado com sucesso.',
                output: $response['output'] ?? null
            );
        } catch (AppException $e) {
            HttpUtil::jsonResponse(
                response_code: $e->getCode() ?? 500,
                message: $e->getMessage() ?? 'Ocorreu um erro ao criar o contato.',
                output: $e->getDetails() ? ['errors' => $e->getDetails()] : null
            );
        }
    }
}