<?php

class Sistema_Service_VistoriadorAuxiliar
{
    private ?int $idFuncionario;
    private Sistema_Model_Funcionarios $funcionariosModel;
    private Sistema_Model_Usuarios $usuariosModel;
    private Sistema_Model_Empresas $empresasModel;
    private Sistema_Model_EmpresasAgronomos $empresasAgronomosModel;
    private Agro_TemplateRenderer $templateRenderer;
    private Sistema_Model_VistoriadoresStatus $vistoriadoresStatusModel;

    public function __construct(?int $idFuncionario)
    {
        $this->idFuncionario = $idFuncionario;
    }

    /**
     * @param int $idStatusVistoriador
     * @return void
     * @throws Zend_Db_Table_Exception
     * @throws Zend_Exception
     */
    public function enviarEmailAgronomosResponsaveis(int $idStatusVistoriador, int $idVistoriadorStatusIgnorar = 0): void
    {
        if (!$this->deveNotificar($idStatusVistoriador)) {
            return;
        }

        if ($this->temStatusConferidoAnterior($idVistoriadorStatusIgnorar)) {
            
            return;
        }
        
        $funcionario = $this->obterFuncionario();
        $usuario = $this->obterUsuarioDoFuncionario($funcionario);

        if (!$this->usuarioEhVistoriadorValido($usuario)) {
            return;
        }

        $empresaId = $this->obterEmpresaDoFuncionario();
        $agronomos = $this->obterAgronomosResponsaveis($empresaId);
        
        $this->enviarEmail($agronomos, $funcionario, $empresaId);
    }

    private function deveNotificar(int $idStatusVistoriador): bool
    {
        return $idStatusVistoriador === Sistema_Model_VistoriadoresStatus::ID_STATUS_CONFERIDO;
    }

    private function temStatusConferidoAnterior(int $idVistoriadorStatusIgnorar): bool
    {
        return $this->getVistoriadoresStatusModel()->hasStatusConferido($this->idFuncionario, $idVistoriadorStatusIgnorar);
    }

    /**
     * @return Zend_Db_Table_Row_Abstract
     * @throws Zend_Db_Table_Exception
     * @throws Zend_Exception
     */
    private function obterFuncionario(): Zend_Db_Table_Row_Abstract
    {
        if (empty($this->idFuncionario)) {
            throw new Zend_Exception('Vistoriador/Auxiliar não informado.');
        }

        $funcionario = $this->getFuncionariosModel()
            ->find($this->idFuncionario)
            ->current();

        if (empty($funcionario)) {
            throw new Zend_Exception('Funcionário não encontrado.');
        }

        return $funcionario;
    }

    /**
     * @throws Zend_Db_Table_Exception
     */
    private function obterUsuarioDoFuncionario(Zend_Db_Table_Row_Abstract $funcionario): ?Zend_Db_Table_Row_Abstract
    {
        return $this->getUsuariosModel()
            ->find($funcionario['id_usuario'])
            ->current();
    }

    private function usuarioEhVistoriadorValido($usuario): bool
    {
        $specification = new Sistema_Model_Specification_UsuarioTipoPerfil(
            [Sistema_Model_Usuarios::TIPO_USUARIO_VISTORIADOR],
            [
                Sistema_Model_Usuarios::PERFIL_VISTORIADOR,
                Sistema_Model_Usuarios::PERFIL_VISTORIADOR_RESPONSAVEL
            ]
        );

        return $specification->usuarioDeAcordoTipoPerfil($usuario);
    }

    /**
     * @throws Zend_Exception
     */
    private function obterEmpresaDoFuncionario(): int
    {
        $empresaId = $this->getEmpresasModel()
            ->getIdEmpresaUsuario($this->idFuncionario);

        if (empty($empresaId)) {
            throw new Zend_Exception('Empresa do funcionário não encontrada.');
        }

        return $empresaId;
    }

    private function obterAgronomosResponsaveis(int $empresaId): array
    {
        return $this->getEmpresasAgronomosModel()
            ->getAgronomoByEmpresa($empresaId);
    }

    /**
     * @throws Zend_Exception
     */
    private function enviarEmail(array $agronomos, Zend_Db_Table_Row_Abstract $funcionario, int $empresaId): void
    {
        try {
            $mail = new Agro_Mail();

            foreach ($agronomos as $agronomo) {
                $mail->addTo($agronomo['ds_email']);
            }

            $mail->inicioTextoPadrao(false);
            $mail->setSubject('Novo Vistoriador Cadastrado');

            $mail->setBodyHtml(
                $this->getTemplateRenderer()->renderizar(
                    '/sinistro/vistoriador_auxiliar/cadastro_conferido.html.tpl',
                    [
                        'nome_vistoriador' => $funcionario['ds_nome_funcionario'],
                        'nome_empresa' => $this->getEmpresasModel()
                            ->getNomeEmpresaById($empresaId),
                    ]
                )
            );

            $mail->send();

        } catch (Throwable $exception) {
            throw new Zend_Exception('Erro ao enviar e-mail para o(s) agrônomo responsável(is).');
        }
    }

    private function getFuncionariosModel(): Sistema_Model_Funcionarios
    {
        return $this->funcionariosModel ??= new Sistema_Model_Funcionarios();
    }

    private function getUsuariosModel(): Sistema_Model_Usuarios
    {
        return $this->usuariosModel ??= new Sistema_Model_Usuarios();
    }

    private function getEmpresasModel(): Sistema_Model_Empresas
    {
        return $this->empresasModel ??= new Sistema_Model_Empresas();
    }

    private function getEmpresasAgronomosModel(): Sistema_Model_EmpresasAgronomos
    {
        return $this->empresasAgronomosModel ??= new Sistema_Model_EmpresasAgronomos();
    }

    private function getTemplateRenderer(): Agro_TemplateRenderer
    {
        return $this->templateRenderer ??= new Agro_TemplateRenderer();
    }

    private function getVistoriadoresStatusModel(): Sistema_Model_VistoriadoresStatus
    {
        return $this->vistoriadoresStatusModel ??= new Sistema_Model_VistoriadoresStatus();
    }
}