<?php

namespace App\Controllers;

use App\Libraries\Zdg;
use App\Models\FaturaModel;
use App\Models\FaturaFormapgtoModel;
use App\Models\ClienteModel;
use App\Models\ClientePedidoModel;
use App\Models\EvuptContatoModel;
use App\Models\EvuptDisparadorModel;
use App\Models\EvuptTemplateModel;
use App\Models\OrganizacaoModel;
use App\Models\ProdutoModel;
use DateTime;
use DateTimeZone;

class Crontask extends BaseController
{


    /**
     * INDEX}  
     * constroi a secao Index : nada para mostrar
     * 
     */
    public function index(){

        die;

        // inicia o serviço de email do sistema
        $email = \Config\Services::email();
        $config = [
            'protocol'  => 'smtp',
            'SMTPHost'  => 'mail.nucleodenegociosweb.com.br',
            'SMTPUser'  => 'adm@nucleodenegociosweb.com.br',
            'SMTPPass'  => 'lucr4tivo!',
            'SMTPPort'  => '587',
            'wordWrap'  => true,
            'mailType'  => 'html',
        ];
        
        $email->initialize($config);
        $email->setFrom('adm@nucleodenegociosweb.com.br', 'teste');
        $email->setTo('lecowd@gmail.com');
        $email->setSubject('CRON} Testou!');

        $message = 'BOA!';

        // define template para o email
        $email->setMessage($message);

        // envia mensagem
        if (! $email->send()):
            // se apresentou erro, add ao relatorio.
            var_dump($email->printDebugger());
            echo '<hr>';
            var_dump($email->printDebugger(['headers']));
        endif;
    }



    /**
     * ABRIR FATURAS }
     * constroi a secao abrir novas faturas recorrentes
     *      roda diariamente às 8am
     * 
     */
    public function rodar() {

        helper(['funcoes']);

        //define dia de hoje
        $dia = date_create();
        $dia = date_format($dia, 'd/m/Y');
        
        //define dia de hoje + 7 dias
        $diahoje = date_create();
        date_modify($diahoje,'+7 day');
        $diahoje = date_format($diahoje, 'Y-m-d');

        //define dia de hoje mes anterior
        $ultimomes = date_create();
        date_modify($ultimomes,'-1 month');
        $ultimomes = date_format($ultimomes, 'Y-m-d');
        
        //define dia de hoje + 1 mes
        $proximomes = date_create();
        $proximomes = date_modify($proximomes,'+1 month');
        $proximomes = date_format($proximomes, 'Y-m-d');

        //variáveis para relatorio
        $RelatorioNovasFaturas = 0;
        $RelatorioNovosJuros = 0;

        //seleciona todos os pedidos com status aberto
        $clientePedidoModel = new ClientePedidoModel();
        $clientePedidoModel->join('cliente','cliente_pedido.id_cliente=cliente.id_cliente');
        $clientePedidoModel->join('produto','cliente_pedido.id_produto=produto.id_produto');
        $clientePedidoModel->where('cliped_status=1');
        $indPedidos = $clientePedidoModel->findAll();

        $faturaModel = new FaturaModel();

        //enquanto houver pedidos com status aberto confere
        foreach($indPedidos as $p):

            //se produto vence em 7 dias (semana que vem) ($diahoje,'+7 day');
            if( $diahoje >= dataEUA($p['cliped_pagamentoproximo'])):

                //seleciona todas as faturas abertas deste pedido
                $array = array('fat_status' => '1', 'id_pedido' => $p['id_clientepedido']);
                $faturaModel->where($array);
                $indFaturas = $faturaModel->findAll();

                //se não existir faturas abertas. se as faturas estiverem todas pagas
                if(empty($indFaturas)):

                    //+++++++++++++++++++++++++++++++++++++++++++++ echo "criar nova fatura do período ########################## : ";
                    ###01

                    //pega o nome do produto
                    $produtoModel = new ProdutoModel();
                    $pro_nome = $produtoModel->where('id_produto',$p['id_produto'])->withDeleted()->first();

                    //define os períodos e datas do produto
                    $datainicio = dataBrasil($p['cliped_pagamentoproximo'],'data');
                    $datafim = date_create($p['cliped_pagamentoproximo']);
                    switch($p['cliped_pagamentoperiodo']):
                        //anual
                        case 1 :
                        date_modify($datafim, "+1 year");
                        break;
                        //trimestral
                        case 3 :
                        date_modify($datafim, "+3 month");
                        break;
                        //semestral
                        case 6 :
                        date_modify($datafim, "+6 month");
                        break;
                        //mensal
                        case 8 :
                        date_modify($datafim, "+1 month");
                        break;
                        default :
                        date_modify($datafim, "+1 month");
                        break;
                    endswitch;

                    //ajuste para o ciclo de cobranca
                    date_modify($datafim, "-1 day");
                    $datafim = date_format($datafim, 'd/m/Y');

                    //define dia de abertura da fatura
                    $aberturaFatura = date_create($p['cliped_pagamentoproximo']);
                    date_modify($aberturaFatura, "-7 day");
                    $aberturaFatura = date_format($aberturaFatura, 'Y-m-d');

                    //encapsula dados da nova fatura
                    $dados = array(
                        'id_cliente'		=>	$p['id_cliente'],
                        'fat_descricao'		=>	$pro_nome['pro_nome'].' ('.$datainicio.' - '.$datafim.') '.$p['cliped_dominio'],
                        'fat_valor'	    	=>	$p['cliped_valor'],
                        'fat_data'	 	    =>	$aberturaFatura,
                        'fat_vencimento'	=>	$p['cliped_pagamentoproximo'],
                        'fat_pagamento' 	=>	NULL,
                        'fatfor_nome'		=>	'7',
                        'fat_status'		=>	'1',
                        'id_pedido'         =>  $p['id_clientepedido'],
                    );

                    //insere nova fatura na base de dados
                    $faturaModel->resetQuery();
                    $sucesso = $faturaModel->insert($dados);
                    if($sucesso == TRUE):
                        $RelatorioNovasFaturas = $RelatorioNovasFaturas+1;
                    else:
                        $RelatorioNovasFaturas = $RelatorioNovasFaturas;
                        echo "erro #02";
                        exit;
                    endif;

                //se já existir uma fatura 'aberta' deste 'pedido'
                else:

                    //Cria contador verificando nas faturas
                    $i = 0;
                    foreach($indFaturas as $f):

                        //se tiver fatura criada com menos de 30 dias do vencimento, adiciona 1
                        if(dataEUA($f['fat_vencimento']) >= $ultimomes):
                            $i = $i+1;
                        else:
                            $i = $i;
                        endif;
        
                        //define e busca #
                        $agulha   = '&#35;';
                        $palheiro = $f['fat_descricao'];
                        $pos = strpos( $palheiro, $agulha );

                        //se alguma fatura não tiver juros, adiciona 1
                        if ( $pos === false) :
                            $i = $i+1;
                        endif;

                    endforeach;

                    //se só existir fatura atrasada para o produto adiciona nova na data da cron
                    if($i == 0):

                        //echo "tem fatura atrasada, mas precisa criar fatura";
                        //+++++++++++++++++++++++++++++++++++++++++++++ [ criar nova  fatura ]
                        ###02
                        //pega o nome do produto
                        $produtoModel = new ProdutoModel();
                        $produtoModel->resetQuery();
                        $pro_nome = $produtoModel->where('id_produto',$p['id_produto'])->withDeleted()->first();
                        
                        //ajusta periodo do produto
                        $datainicio = date_create('now');
                            date_format($datainicio,'Y-m-d');
                        $datafim = date_create('now');
                            date_format($datafim,'Y-m-d');
                        switch($p['cliped_pagamentoperiodo']):
                            //anual
                            case 1 :
                            date_modify($datafim, "+1 year");
                            break;
                            //trimestral
                            case 3 :
                            date_modify($datafim, "+3 month");
                            break;
                            //semestral
                            case 6 :
                            date_modify($datafim, "+6 month");
                            break;
                            //mensal
                            case 8 :
                            date_modify($datafim, "+1 month");
                            break;
                            default :
                            date_modify($datafim, "+1 month");
                            break;
                        endswitch;

                        //ajusta data do ciclo de cobranca
                        $datafim = date_modify($datafim, "+6 days");
                        $datafim = date_format($datafim, "d/m/Y");

                        //define dia de abertura da fatura
                        $aberturaFatura = $datainicio;
                        $aberturaFatura = date_format($aberturaFatura, 'Y-m-d');

                        //define dia de vencimento da fatura
                        $dataultimafaturaAberta = $datainicio;
                        $dataultimafaturaAberta = date_modify($dataultimafaturaAberta,'+ 7days');
                        $dataultimafaturaAberta = date_format($dataultimafaturaAberta,'Y-m-d');
        
                        $datainicio = date_format($datainicio, 'd/m/Y');

                        //encapsula dados para nova fatura
                        $dados = array(
                            'id_cliente'		=>	$p['id_cliente'],
                            'fat_descricao'		=>	$pro_nome['pro_nome'].' ('.$datainicio.' - '.$datafim.') '.$p['cliped_dominio'],
                            'fat_valor'	    	=>	$p['cliped_valor'],
                            'fat_data'	 	    =>	$aberturaFatura,
                            'fat_vencimento'	=>	$dataultimafaturaAberta,
                            'fat_pagamento' 	=>	NULL,
                            'fatfor_nome'		=>	'1',
                            'fat_status'		=>	'1',
                            'id_pedido'         =>  $p['id_clientepedido'],
                        );

                        //insere nova fatura e recebe retorno
                        $faturaModel->resetQuery();
                        $sucesso = $faturaModel->insert($dados);
                        if($sucesso == TRUE):
                            $RelatorioNovasFaturas = $RelatorioNovasFaturas+1;
                        else:
                            $RelatorioNovasFaturas = $RelatorioNovasFaturas;
                            echo "erro #03";
                            exit;
                        endif;
                    endif;
                endif;
            endif;
        endforeach;
        

        //Adiciona juros a fatura em aberto. Adiciona juros a fatura não paga após a data de vencimento
        
        //seleciona todas as faturas em aberto
        $faturaModel->resetQuery();
        $indsFatura = $faturaModel->where('fat_status','1')->findAll();
        
        //verifica uma a uma
        foreach($indsFatura as $r):

            //se está atrasada
            $fat_vencimento = dataEUA($r['fat_vencimento']);
            $dia = dataEUA($dia);
            if($dia>$fat_vencimento):

                //define e busca #
                $agulha   = '&#35;';
                $palheiro = $r['fat_descricao'];
                $pos = strpos( $palheiro, $agulha );

                //adiciona juros se nao possuir juros adicionado . juros adicionado apenas uma vez por fatura atrasada
                if ( $pos === false) :
                    
                    //calcula juros 10%
                    //$valorOriginal = str_replace('.','',$r['fat_valor']);
                    //$valorOriginal = str_replace(',','.',$valorOriginal);
                    //$percentual = $valorOriginal*0.1;
                    //$valorAtualizado = $valorOriginal+$percentual;
                    //$valorAtualizado = number_format($valorAtualizado, 2, ',', '.'); // retorna R$100.000,50
                    //$percentual = number_format($percentual, 2, ',', '.'); // retorna R$100.000,50
                    
                    //encapsula dados
                    $dados = array(
                        'id_cliente'		=>	$r['id_cliente'],
                        //'fat_descricao'		=>	$r['fat_descricao'] . ' '.$agulha.' Juros adicionado por atraso R$'.$percentual,
                        //'fat_descricao'		=>	$r['fat_descricao'] . ' '.$agulha.' Juros adicionado por atraso.',
                        'fat_descricao'		=>	$r['fat_descricao'] . ' '.$agulha.' Fatura vencida.',
                        //'fat_valor'	    	=>	$valorAtualizado,
                        'fat_valor'	    	=>	$r['fat_valor'],
                        'fat_data'	 	    =>	$r['fat_data'],
                        'fat_vencimento'	=>	$r['fat_vencimento'],
                        'fat_pagamento' 	=>	$r['fat_pagamento'],
                        'fatfor_nome'		=>	$r['fatfor_nome'],
                        'fat_status'		=>	$r['fat_status'],
                        'id_pedido'         =>  $r['id_pedido'],
                    );
                    //atualiza base de dados
                    $faturaModel->resetQuery();
                    $sucesso = $faturaModel->update($r['id_fatura'], $dados);
                    if($sucesso == TRUE):
                        $RelatorioNovosJuros = $RelatorioNovosJuros+1;
                    else:
                        $RelatorioNovosJuros = $RelatorioNovosJuros;
                        echo "erro #02";
                        exit;
                    endif;

                    
                endif;
            endif;

        endforeach;


        // inicia o serviço de email do sistema
        $organizacaoModel = new OrganizacaoModel();
        $organizacao = $organizacaoModel->first();
        $organizacaoModel->resetQuery();
        $email = \Config\Services::email();
        $config = [
            'protocol'  => $organizacao['org_email_protocol'],
            'SMTPHost'  => $organizacao['org_email_smtp'],
            'SMTPUser'  => $organizacao['org_email_disparo'],
            'SMTPPass'  => $organizacao['org_email_senha'],
            'SMTPPort'  => $organizacao['org_email_port'],
            'wordWrap'  => true,
            'mailType'  => 'html',
        ];
        $email->clear(true);
        $email->initialize($config);
        $email->setFrom($organizacao['org_email'], $organizacao['org_nome_fantasia']);
        $email->setTo('lecowd@gmail.com'); //administrador do sistema
        $email->setSubject('Qualixlav Cron} Bom dia, completei o ciclo de hoje.');

        $message = '<html><head></head><body>';
        $message .= '<table width=100% cellpadding=10 border=0 style="text-align:center;">';
        $message .= '<tr>';
        $message .= '<td colspan=2><h3>Rodou a Cron dia '.$dia.'</h3><td>';
        $message .= '</tr>';
        $message .= '<tr>';
        $message .= '<td>Total faturas criadas: <h1>'.$RelatorioNovasFaturas.'</h1></td>';
        $message .= '<td>Total faturas com juros adicionados: <h1>'.$RelatorioNovosJuros.'</h1></td>';
        $message .= '</tr>';
        $message .= '<tr>';
        $message .= '<td colspan=2><center><a href="' . base_url() . '" title="acesse">' . base_url() . '</a></small></center><small><td>';
        $message .= '</tr>';
        $message .= '</table>';
        $message .= '<body></html>';

        // define template para o email
        $email->setMessage($message);

        // envia mensagem
        if (! $email->send()):
            // se apresentou erro, add ao relatorio.
            var_dump($email->printDebugger());
        endif;

    }



    /**
     * EVUPT MOTOR }
     * dispara alertas existentes no sistema
     *      diariamente a cada 15 minutos
     *      entre 8 e 17 de segunda à sexta todos as semanas
     * 
     */
    public function evuptMotor(){
        
        // não dispara se antes 8h ou depois 12h e antes das 14h ou depois das 18h
        $dataHoje = date_create('NOW', new DateTimeZone('America/Sao_Paulo'));
        $alarme = date_format($dataHoje,'H');
        $alarmeLigado = false;

        if(($alarme < '8' || $alarme > '11') && ($alarme < '14' || $alarme > '17' ) && $alarmeLigado):
            echo ' - fora do horário - ';
            return false;
            die;
        else:    
            echo '...... motor ligou';
            echo '<br>';
        endif;

        // seleciona todos os disparadores ativos
        $evuptDisparadorModel = new EvuptDisparadorModel();
        $evuptDisparadorModel->select('*');
        $disparadores = $evuptDisparadorModel->findAll();

        // a cada disparador que retornou
        foreach($disparadores as $d):
            echo $d['id_disparador'] . ' ' . $d['dis_nome'] . '<br>';
            
            // seleciona templates ativos do disparador
            $evuptTemplateModel = new EvuptTemplateModel();
            $evuptTemplateModel->where('id_disparador',$d['id_disparador']);
            $evuptTemplateModel->where('tem_status',1);
            $template = $evuptTemplateModel->findAll();
            
            // a cada template ativo
            foreach($template as $t):
                echo ' . . ' . $t['id_template'] . '. ' . $t['tem_titulo'] . '<br>';

                // verifica a data de cadastro - prazoz = hoje
                $dataHoje = date_create('now', new DateTimeZone('America/Sao_Paulo'));
                date_modify($dataHoje,'- ' . $t["tem_prazo"] . 'days');

                // seleciona clientes 
                //                      do disparador
                //                      ativos
                //                      // no tem_prazo // desativado // e substituido pela linha abaixo
                //                      maior ou igual ao tem_prazo
                //                      que não disparou template
                //                      2 total de registros por vez
                $evuptContatoModel = new EvuptContatoModel();
                $evuptContatoModel->where('id_disparador',$d['id_disparador']);
                $evuptContatoModel->where('con_status',1);
                // $evuptContatoModel->where('DATE(created_at)',date_format($dataHoje,'Y-m-d'));
                $evuptContatoModel->where('created_at<=',date_format($dataHoje,'Y-m-d H:i:s'));
                $evuptContatoModel->notLike('con_relatorio', '{"' . $t['id_template'] .'":true}');
                $contato = $evuptContatoModel->findAll(2);
                
                echo $evuptContatoModel->getLastQuery();
                echo '<br>';
                echo '<br>';

                $evuptContatoModel->resetQuery();
                //echo $evuptContatoModel->getLastQuery();

                // se houver clientes com prazo
                if($contato):

                    // a cada cliente ativo
                    foreach($contato as $c):

                        // ajusta variáveis da mensagem
                        $find = array(
                            '{{nome}}',
                        );
                        $replace = array(
                            'nome' => $c['con_nome'],
                        );
                        $mensagem = str_replace($find, $replace, $t['tem_corpo']);

                        // DISPARO WHATS E EMAIL
                        // se tiver whats e e email, envia para os dois
                        
                        if($c['con_whats']):
                            $zdg = new Zdg($d['dis_boturl'],$d['dis_botauth'],$d['dis_bothash']);
                            $zdg->numero($c['con_whats']);
                            $retorno = $zdg->sendMessage($mensagem);
                            echo 'Disparo whats: ' . $retorno;
                            echo 'whats<br>';
                        endif;

                        if($c['con_email']):
                            $template = '<html><head>';
                            $template .= '<style>';
                            $template .= ':root {';
                            $template .= '--font: "Arial, sans-serif";';
                            $template .= '}';
                            $template .= 'body {';
                            $template .= 'font-family: var(--font, "Helvetica, sans-serif");';
                            $template .= '}';
                            $template .= '</style>';
                            $template .= '</head><body>';
                            $template .= '<table border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" style="background-color:rgb(244,244,244)">';
                            $template .= '<tr>';
                            $template .= '<td align="center" valign="top">';
                            $template .= '<table width="600px" cellpadding="10" cellspacing="0" border=0 style="text-align:left; background-color:#FFFFFF">';
                            $template .= '<tr>';
                            $template .= '<td>';
                            $template .= nl2br($mensagem);
                            $template .='<img src="'. base_url() .'/retorno/pixel?userid='.$c['id_contato'].'&amp;campaign='.$t['id_template'].'&amp;more=from_evupt">';
                            $template .= '</td>';
                            $template .= '</tr>';
                            $template .= '</table>';
                            $template .= '<table width="600px" cellpadding="10" cellspacing="0" border=0 style="text-align:left; background-color:#FFFFFF">';
                            $template .= '<tr>';
                            $template .= '<td>';
                            $template .= '<br>';
                            $template .= '<hr>';
                            $template .= '<br>';
                            $template .= '<center><small>Você está recebendo este email por que solicitou a entrada em nossa lista em algum momento.<br> ' . anchor('evupt/inscricaoCancela/'.$d['id_disparador'].':'.$c['con_email'],'Clique Aqui e Cancele') . ' sua inscrição caso não seja mais pertinente receber descontos e dicas de como ter uma vida mais tranquila e economizar.</small></center>';
                            $template .= '</td>';
                            $template .= '</tr>';
                            $template .= '</table>';
                            $template .= '</td>';
                            $template .= '</tr>';
                            $template .= '</table>';
                            $template .= '<body></html>';
                            $retorno = $this->MotorDisparaEmail($d['id_disparador'],$c['con_email'],$t['tem_titulo'],$template);
                            echo 'Disparo email: ' . $retorno;
                            echo 'email<br>';
                        endif;
                        
                        // mostra mensagem na tela mensagem
                        echo $c['con_nome'] . ' mensagem: <br>';
                        echo $mensagem;
                        echo '<br>';

                        // se primeiro relatorio, transforma em array o campo vazio
                        if($c['con_relatorio']==null):
                            $c['con_relatorio'] = [];
                        else:
                            $c['con_relatorio'] = json_decode($c['con_relatorio'], true);
                        endif;

                        // adiciona novo relatorio ao array
                        array_push($c['con_relatorio'],[$t['id_template'] => true]);

                        // transforma array em json
                        $salvajson = json_encode($c['con_relatorio']);

                        // salva relatório na base do contato
                        $evuptContatoModel->update($c['id_contato'],['con_relatorio'=>$salvajson]);
                        $evuptContatoModel->resetQuery();
        
                        // aguarda uns segundos aleatórios
                        sleep(rand(0,2));
                    endforeach;
                else:
                    echo 'nenhum retorno obtido.';
                endif;
                echo '<hr>';
                
            endforeach;

        endforeach;

        //
        echo '<br>';
        echo '...... desligou';
    }


    /**
     * MOTOR EMAIL } 
     * cria estrutura de disparo dos emails
     * 
     * @param $id_disparador
     * @param $contato_email
     * @param $contato_assunto
     * @param $mensagem
     * @return bool
     */
    private function motorDisparaEmail($id_disparador,$con_email,$assunto,$mensagem){

        // seleciona o disparador que alimenta o motor
        $disparadorModel = new EvuptDisparadorModel();
        $disparador = $disparadorModel->where('id_disparador',$id_disparador)->first();
        
        // inicia o serviço de email do sistema
        $email = \Config\Services::email();
        $config = [
            'protocol'  => $disparador["dis_secure"]? 'smtp' : 'mail',
            'SMTPHost'  => $disparador["dis_smtp"],
            'SMTPUser'  => $disparador["dis_email"],
            'SMTPPass'  => $disparador["dis_senha"],
            'SMTPPort'  => $disparador["dis_secure"]? '587' : '465',
            'wordWrap'  => true,
            'mailType'  => 'html',
        ];
        $email->clear(true);
        $email->initialize($config);
        $email->setFrom( $disparador["dis_email"] , $disparador["dis_email"]);
        $email->setTo($con_email);
        $email->setReplyTo($disparador["dis_reply"]);
        $email->setSubject($assunto);
        $email->setMessage($mensagem);

        // envia mensagem e retorna resultado
        if (! $email->send()):
            // se apresentou erro, add ao relatorio.
            return $email->printDebugger();
        else:
            return true;
        endif;
    }



}