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

use Ramsey\Uuid\Uuid;
use WorkbloomERP\Utils\SanitizeUtil;
use WorkbloomERP\Utils\ValidateUtil;
use WorkbloomERP\Services\DBService;
use WorkbloomERP\Exceptions\AppException;
use WorkbloomERP\Module\v0\Auth\Utils\AuthUtil;
use WorkbloomERP\Module\v0\Empresa\Repos\EmpresaRepo;
use WorkbloomERP\Module\v0\Contato\Repos\ContatoRepo;
use WorkbloomERP\Module\v0\Empresa\Models\EmpresaModel;
use WorkbloomERP\Module\v0\Contato\Models\ContatoModel;
use WorkbloomERP\Module\v0\Contato\DTOs\ContatoCreateDTO;
use WorkbloomERP\Module\v0\Contato\Factories\ContatoServiceFactory;
use WorkbloomERP\Constants\SpedCRTConst;
use WorkbloomERP\Constants\BrasilUfsConst;
use WorkbloomERP\Constants\SpedPaisesConst;
use WorkbloomERP\Module\v0\Contato\Constants\OrgaoPublicoConst;
use WorkbloomERP\Module\v0\Contato\Constants\PersonalidadeConst;
use WorkbloomERP\Module\v0\Contato\Constants\ContribuinteICMSConst;
use WorkbloomERP\Module\v0\Contato\Constants\NFSeConsumoIbsCbsConst;

class ContatoService {
    public function __construct (
        protected DBService $db,
        protected ContatoRepo $contatoRepo,
        protected EmpresaRepo $empresaRepo,
    ) {}

    public function createOptions(): array {
        return [
            'tipo' => PersonalidadeConst::getAll(),
            'personalidade' => PersonalidadeConst::getAll(),
            'uf' => BrasilUfsConst::getAll(),
            'regime_tributario' => SpedCRTConst::getAll(),
            'contribuinte_icms' => ContribuinteICMSConst::getAll(),
            'info_uso_consumo_ibs_cbs' => NFSeConsumoIbsCbsConst::getAll(),
            'orgao_publico' => OrgaoPublicoConst::getAll(),
            'paises_sped' => SpedPaisesConst::getAll()
        ];
    }

    public function create(ContatoCreateDTO $contatoCreateDTO): array {
        try {
            return $this->db->transaction(
                callback: function() use ($contatoCreateDTO)  {
                    // Pega as informações da sessão para associar o contato à empresa correta
                    $empresaData = AuthUtil::readSession(key: 'empresa_data');

                    // Verifica se a empresa existe
                    $empresaModel = $this->empresaRepo->findByIdentifier(identifier: 'uuid', value: $empresaData['uuid']);

                    // Cria a fábrica de contato e valida os dados de criação do contato
                    $contatoFactory = ContatoServiceFactory::makeContratoFactory(empresaModel: $empresaModel, contatoCreateDTO: $contatoCreateDTO);
                    $contatoModel = $contatoFactory->create(contatoCreateDTO: $contatoCreateDTO, empresaModel: $empresaModel);

                    return [
                        'response_code' => 201,
                        'message' => 'Contato criado com sucesso.',
                        'output' => ['data' => $contatoModel->toArray()]
                    ];
                }
            );
        } catch(AppException $e) {
            throw $e;
        }
    }
}