<?php

use PhpAmqpLib\Message\AMQPMessage;

require_once __DIR__ . '/../../../../vendor/autoload.php';
require_once 'Zend/Loader/Autoloader.php';

$loader = Zend_Loader_Autoloader::getInstance();

require_once __DIR__ . '/../RpcServerBase.php';

class Agro_RabbitMQ_ImportarHabilitacoes_RpcServer extends Agro_Rabbitmq_RpcServerBase
{
    const PATH_LOG = __DIR__ . "/../../../application/upload_files/log_rabbitmq/";
    const ASSUNTO_EMAIL = 'Conclusão do Processo de importação de Habilitações de Corretores/Sublogins';
    public $conteudo_email = 'Importação de habilitações concluída com sucesso!';
    public $db;
    public $client = null;
    public $header = null;
    public $response = null;
    public $result = null;

    public function __construct(string $func, string $env, string $nomeFila)
    {
 
        parent::__construct($func, $env);
        $this->nomeFila = $nomeFila;

        $porta = (
            array_key_exists(
            'resources.db.params.port',$this->settings[$this->env]
            )?
            $this->settings[$this->env]['resources.db.params.port']
            :'5432'
        );

        $conexao = [
            'host' => $this->settings[$this->env]['resources.db.params.host'],
            'port' => $porta,
            'dbname' => $this->settings[$this->env]['resources.db.params.dbname'],
            'username' => $this->settings[$this->env]['resources.db.params.username'],
            'password' => $this->settings[$this->env]['resources.db.params.password'],
        ];

        $adapter = Zend_Db::factory('PDO_PGSQL', $conexao);
        Zend_Db_Table_Abstract::setDefaultAdapter($adapter);
        $this->db = Zend_Db_Table::getDefaultAdapter();


        if (!file_exists($this::PATH_LOG)) {
            mkdir($this::PATH_LOG, '0755', true);
        }
     
    }

    public function process(AMQPMessage $msg) {
        try { 
            echo "[SERVER] - process: begin\n";

            $payload = json_decode($msg->getBody(), true);
            
            //print_r($payload);
            $this->{$this->func}($payload);

            $msg->get('channel')->basic_ack(
                $msg->get('delivery_tag'), 1
            );
            echo "[SERVER] - process: end\n";
        } catch (\Exception $e) {
            print_r($e->getMessage());
            $msg->get('channel')->basic_nack($msg->getDeliveryTag(), false, true);
        }
    }

    public function run($params)
    {
       
        echo "[SERVER] - run: begin\n";
        try {
            $this->db->beginTransaction();
            foreach($params['data'] as $chave => $linhaCsv) {

                if($chave == 'email_notificacao'){
                    $this->notificaConclusaoConfiguracao($linhaCsv);
                    continue;
                }
                try {
                    if (isset($linhaCsv['id_preposto'])) {
                        $this->remove($linhaCsv['id_preposto'], $linhaCsv['id_produto'], $linhaCsv['id_estado']);
                        if (is_array($linhaCsv['municipios'])) {
                            $this->inserirRegistrosPorMunicipio($linhaCsv);
                        }
                    } else {
                        if (is_array($linhaCsv['municipios'])) {
                            $this->inserirRegistrosPorMunicipio($linhaCsv);
                        } elseif ($linhaCsv['id_municipio']) {
                            $this->remove($linhaCsv['id_corretor'], $linhaCsv['id_produto'], $linhaCsv['id_estado'], $linhaCsv['id_municipio']);
                            $insert = array();
                            $insert['id_usuario'] = $linhaCsv['id_corretor'];
                            $insert['id_produto'] = $linhaCsv['id_produto'];
                            $insert['id_estado'] = $linhaCsv['id_estado'];
        
                            $this->db->insert($insert);
                        } elseif ($linhaCsv['habilitar']) {
                            $this->remove($linhaCsv['id_corretor'], $linhaCsv['id_produto'], $linhaCsv['id_estado']);
        
                            $insert = array();
                            $insert['id_usuario'] = $linhaCsv['id_corretor'];
                            $insert['id_produto'] = $linhaCsv['id_produto'];
                            $insert['id_estado'] = $linhaCsv['id_estado'];
                            $this->db->insert($insert);
                        } else {
                            $this->remove($linhaCsv['id_corretor'], $linhaCsv['id_produto'], $linhaCsv['id_estado']);
                        }
                    }
                    // Habilita todos prepostos do Corretor
                    if ($linhaCsv['fl_habilitar_prepostos']) {
                        $sql = "select * from sistema.prepostos where id_corretor = (select id from sistema.corretores where id_usuario = {$linhaCsv['id_corretor']}) and fl_ativo = true";

                        $rsPrepostos = $this->db->fetchAll($sql);

                        if(count($rsPrepostos)) {
                            for($i = 0; $i < count($rsPrepostos); $i++){
                                $this->remove($rsPrepostos[$i]['id_usuario'], $linhaCsv['id_produto'], $linhaCsv['id_estado']);
                            
                                $linhaCsv['id_preposto'] = $rsPrepostos[$i]['id_usuario'];
                                $linhaCsv['ultimo_preposto'] = ($i == (count($rsPrepostos)-1));
                                
                                $idsHabilitacoesEstado = [];
                                $idUsuario = $linhaCsv['id_preposto'];
                                
                                if (empty($linhaCsv['municipios'])) {
                                    $municipiosEstado = $this->getComboMunicipios($linhaCsv['id_estado']);
                                    
                                    foreach ($municipiosEstado as $municipio) {
                                        $linhaCsv['municipios'][] = "{$linhaCsv['id_estado']}#{$municipio['id']}";
                                    }
                                }
                    
                                if(isset($linhaCsv['municipios'])){
                                    foreach ($linhaCsv['municipios'] as $municipio) {
                                        $estadoMunicipio = explode('#', $municipio);
                                        
                                        if (!array_key_exists($estadoMunicipio[0], $idsHabilitacoesEstado)) {
                                    
                                            if(!(int)$estadoMunicipio[1]){continue;}
                                            $insert = [];
                                            $insert['id_usuario'] = (int) $idUsuario;
                                            $insert['id_produto'] = (int) $linhaCsv['id_produto'];
                                            $insert['id_estado'] = (int) $estadoMunicipio[0];
                                            
                                            $this->db->insert("produto.produtos_habilitacoes", $insert);
                    
                                            $idRowProdutoHabilitacao = $this->db->lastInsertId();
                                        
                                            $idsHabilitacoesEstado[$estadoMunicipio[0]] = $idRowProdutoHabilitacao;
                                        }
                        
                                        $insertHabilitacoesMunicipios = [
                                        'id_produtos_habilitacoes' => (int)$idsHabilitacoesEstado[$estadoMunicipio[0]],
                                        'id_municipio' => (int)$estadoMunicipio[1], 
                                        ];
                                        
                                        $this->db->insert("produto.produtos_habilitacoes_municipios", $insertHabilitacoesMunicipios);
                                    }
                                }
                            }
                       
                        }
                    }
                
                } catch (Exception $e) {
                    echo "[SERVER] - run: ".$e->getMessage()."\n";
                    $this->db->rollback();
                    throw $e;
                }
            }

            $this->db->commit();
            echo "[SERVER] - run: end\n";
            echo "####################################\n";
        } catch (\Throwable $th) {
            echo "[SERVER] - run: Falha na execução\n";
            echo "[ERROR] - {$th->getMessage()}\n";
            
        }

    }
    /**
    * Notifica a conclusão do procedimento para um corretor responsável.
    *
    * @param int $id_corretor O ID de usuário do corretor que será notificado.
    * @return void
    */
    private function notificaConclusaoConfiguracao($email)
    {
        try {
            $config = array(
                'ssl' => $this->settings[$this->env]['constants.MAIL_SSL'],
                'port' => $this->settings[$this->env]['constants.MAIL_PORT'],
                'auth' => $this->settings[$this->env]['constants.MAIL_AUTH'],
                'username' => $this->settings[$this->env]['constants.MAIL_USERNAME'],
                'password' => $this->settings[$this->env]['constants.MAIL_PASSWORD']
            );
            
		    $To = FILTER_VAR($email, FILTER_VALIDATE_EMAIL) ? $email : false;
            if(!$To){
                throw Exception('Endereço de email do corretor inválido.');
            }
            
            $transport = new Zend_Mail_Transport_Smtp($this->settings[$this->env]['constants.MAIL_SMTP'], $config);
          
            $mail = new Zend_Mail('UTF-8');
		    $mail->setFrom($this->settings[$this->env]['constants.MAIL_USERNAME'], 'AgroBrasil - Agronet 2.0');
            $mail->addTo($To);
            $mail->setSubject(self::ASSUNTO_EMAIL);
            $mail->setBodyHtml($this->conteudo_email);
            $mail->send($transport);

        } catch (Zend_Mail_Protocol_Exception $err) {
            print_r($err->getMessage());
        } catch (Exception $e) {
            print_r($e->getMessage());
        }
    }

    public function getComboMunicipios($idEstado, $useEmpty=true, $comboChaveValor = false)
    {
        $idEstado = !filter_var($idEstado,FILTER_VALIDATE_INT) ? 0 : (int)$idEstado;
        $sql = "select id, ds_nome_municipio from sistema.municipios where id_estado = {$idEstado}";

        $rs = $this->db->fetchAll($sql);

        $ret = array();
        if (count($rs)) {
            if ($useEmpty) {
                $ret[0] = array(
                    'id' => '',
                    'nome' => ''
                );
            }

            foreach ($rs as $Row) {
                if ($comboChaveValor) {
                    $ret[$Row->id] = $Row['ds_nome_municipio'];
                } else {
                    $ret[] = array(
                        'id' => $Row['id'],
                        'nome' => $Row['ds_nome_municipio']
                    );
                }
            }
        }

        return $ret;
    }

    private function remove($idUsuario, $idProduto, $idEstado, $idMunicipio=false)
    {
        $sql = "SELECT * FROM produto.produtos_habilitacoes where id_produto = {$idProduto} AND id_usuario = {$idUsuario} and id_estado = {$idEstado}";

        $rowProdutoHabilitacao = $this->db->fetchRow($sql);
        if (!empty($rowProdutoHabilitacao)) {
            if (!empty($idMunicipio)) {
                $this->db->delete(
                    'produto.produtos_habilitacoes_municipios' , 
                    [
                        'id_produtos_habilitacoes = ?' => $rowProdutoHabilitacao['id'],
                        'id_municipio = ?' => $idMunicipio
                    ]
                );
            } else {
                $this->db->delete('produto.produtos_habilitacoes_municipios' , ['id_produtos_habilitacoes = ?' => $rowProdutoHabilitacao['id']]);
            }

            $this->db->delete('produto.produtos_habilitacoes', ['id = ?' => $rowProdutoHabilitacao['id']]);
        }
    }
    private function removeEstados($idUsuario, $idProduto){
        //
    }
    private function inserirRegistrosPorMunicipio(array $data){
        $idsHabilitacoesEstado = [];
        $idUsuario = !empty($data['id_preposto']) ? $data['id_preposto'] : $data['id_corretor'];

        if (isset($data['id_estado'])) {
            $this->remove($idUsuario, $data['id_produto'], $data['id_estado']);
        } else {
            $this->removeEstados($idUsuario, $data['id_produto']);
        }

        if (empty($data['municipios'])) {
            $sql = "SELECT id FROM sistema.municipios where id_estado = {$data['id_estado']}";
            $municipiosEstado = $this->db->fetchAll($sql);
           
            foreach ($municipiosEstado as $municipio) {
                $data['municipios'][] = "{$data['id_estado']}#{$municipio['id']}";
            }
            
        }

        foreach ($data['municipios'] as $municipio) {
            $estadoMunicipio = explode('#', $municipio);
            if (!array_key_exists($estadoMunicipio[0], $idsHabilitacoesEstado)) {
                $insert = [];
                $insert['id_usuario'] = (int) $idUsuario;
                $insert['id_produto'] = (int) $data['id_produto'];
                $insert['id_estado'] = (int) $estadoMunicipio[0];
                
                $sql = "INSERT INTO produto.produtos_habilitacoes (id_usuario,id_produto, id_estado) VALUES (?,?,?) RETURNING id";
                $statement = $this->db->query($sql, [$idUsuario, $data['id_produto'], $estadoMunicipio[0]]);

                $idsHabilitacoesEstado[$estadoMunicipio[0]] = $statement->fetchColumn();
            }

            $sql = [
                'id_produtos_habilitacoes' => (int)$idsHabilitacoesEstado[$estadoMunicipio[0]],
                'id_municipio' => (int)$estadoMunicipio[1]
            ];
            $this->db->insert("produto.produtos_habilitacoes_municipios", $sql);
        }
    }

}