<?php

namespace Source\Models;

use Source\Conn\DataLayer;

class DocNFSe extends DataLayer
{
    private $url = 'https://adn.nfse.gov.br/contribuintes';
    private $urlDanfe = 'https://sefin.nfse.gov.br/sefinnacional';

    public function searchDoc(array $data)
    {

        $result = $this->db()->from('company')
            ->join('certificate', function($join){
                $join->on('certificate_id_company', 'company_id');
            })
            ->where('certificate_trash')->is('0')
            ->andWhere('company_id_user')->is(ID_LOG)
            ->andWhere('company_type_nfse')->is(1)
            ->select()
            ->all();

        if($result){
            foreach($result as $r){
                $start_date = new \DateTime($r->company_ult_date_nfse_primary);
                $since_start = $start_date->diff(new \DateTime(date('Y-m-d H:i:s')));
                $minutes = $since_start->days * 24 * 60;
                $minutes += $since_start->h * 60;
                $minutes += $since_start->i;

                $array_r = ['.', '-', '/'];
                $array_c = ['', '', ''];
                if($minutes < '2'){
                    $this->call(
                        '200',
                        'Ops',
                        '<button type="button" class="btn btn-secondary" data-dismiss="modal">Fechar</button>',
                        "error",
                        "Intervalo de busca inoperante, intervalo deve ser de 2 minutos"
                    )->back(["count" => 0]);
                    return;
                }

                $curl = curl_init("{$this->url}/DFe/{$r->company_nsu_nfse_primary}");
                curl_setopt_array($curl,[
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_MAXREDIRS => 10,
                    CURLOPT_TIMEOUT => 30,
                    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                    CURLOPT_CUSTOMREQUEST => "GET",
                    CURLOPT_SSLCERT => 'shared/certificado/'.$r->certificate_file,
                    CURLOPT_SSLCERTPASSWD => $r->certificate_password,
                    CURLOPT_SSLCERTTYPE => 'P12',
                    CURLOPT_SSL_VERIFYPEER => true,
                    CURLINFO_HEADER_OUT => true
                ]);
                $ret = json_decode(curl_exec($curl));

                if($ret->StatusProcessamento == 'DOCUMENTOS_LOCALIZADOS'){
                    for($x=0;$x<count($ret->LoteDFe); $x++){
                        $content = gzdecode(base64_decode($ret->LoteDFe[$x]->ArquivoXml));
                        $xml = simplexml_load_string($content);


                        $ultNSU = $ret->LoteDFe[$x]->NSU;


                        $resultNFSe = $this->db()->from('nfse')
                            ->where('nfse_id_company')->is($r->company_id)
                            ->andWhere('nfse_chave')->is(trim($ret->LoteDFe[$x]->ChaveAcesso))
                            ->select()
                            ->all();

                        if(!$resultNFSe){
                            $form_nfse['nfse_id_company']   = $r->company_id;
                            $form_nfse['nfse_nsu']          = trim($ret->LoteDFe[$x]->NSU);
                            $form_nfse['nfse_chave']        = trim($ret->LoteDFe[$x]->ChaveAcesso);
                            $form_nfse['nfse_tipo']         = trim($ret->LoteDFe[$x]->TipoDocumento);
                            $form_nfse['nfse_data_hora']    = trim($ret->LoteDFe[$x]->DataHoraGeracao);
                            $form_nfse['nfse_doc']          = trim($xml->infNFSe->emit->CNPJ);
                            $form_nfse['nfse_emitente']     = trim($xml->infNFSe->emit->xNome);
                            $form_nfse['nfse_local_prestacao'] = trim($xml->infNFSe->xLocPrestacao);
                            $form_nfse['nfse_xml']          = base64_encode($content);

                            $form_nfse['nfse_valor_servico'] = trim($xml->infNFSe->DPS->infDPS->valores->vServPrest->vServ);
                            $form_nfse['nfse_tomador_doc']   = trim($xml->infNFSe->DPS->infDPS->toma->CNPJ);
                            $form_nfse['nfse_tomador']       = trim($xml->infNFSe->DPS->infDPS->toma->xNome);

                            $this->db()->insert($form_nfse)->into('nfse');
                        }
                    }
                    $form_company['company_nsu_nfse_primary'] = $ultNSU;
                    $form_company['company_ult_date_nfse_primary'] = date('Y-m-d H:i:s');
                    $this->db()->update('company')->where('company_id')->is($r->company_id)->set($form_company);
                }


                $this->call(
                    '200',
                    'Parabéns',
                    '<button type="button" class="btn btn-secondary" data-dismiss="modal">Fechar</button>',
                    "ok",
                    "Consulta realizada com sucesso"
                )->back(["count" => 0]);
                return;
            }

        }
    }

    /**
     * @param array $data
     * @return void
     */
    public function search(array $data): void{
        $jSONsEARCH['type'] = 'ok';
        $jSONsEARCH['info'] = $data;
        $_SESSION[$data['action']] = $jSONsEARCH;
        echo json_encode($jSONsEARCH);
        return;
    }

    /**
     * @param array $data
     * @return void
     */
    public function searchRead(array $data): void{
        unset($_SESSION[$data['action']]['info']['search']);
        echo json_encode($_SESSION[$data['action']]);
        return;
    }

    /**
     * @param array $data
     * @return void
     */
    public function select(array $data): void
    {
        $start = ($data['pageNo'] * $data['size']) - $data['size'];
        if (empty($data['size'])){
            $max = '300';
        }else{
            $max = $data['size'];
        }

        $forms = $_SESSION[$data['action']]['info'];


        $queryPaginator = $this->db()->from('nfse')
            ->join('company', function($join){
                $join->on('company_id', 'nfse_id_company');
            })->where('nfse_tipo')->is('NFSE')->andWhere('company_id_user')->is(ID_LOG);

        $query = $this->db()->from('nfse')
            ->join('company', function($join){
                $join->on('company_id', 'nfse_id_company');
            })->where('nfse_tipo')->is('NFSE')->andWhere('company_id_user')->is(ID_LOG);




        if($forms['id_empresa'] != ''){
            $queryPaginator = $queryPaginator->andWhere('nfse_id_company')->is($forms['id_empresa']);
            $query = $query->andWhere('nfse_id_company')->is($forms['id_empresa']);
        }
        if($forms['data_inicial'] != '' && $forms['data_final'] != ''){
            $queryPaginator = $queryPaginator->andWhere('nfse_data_hora')->between($forms['data_inicial'],$forms['data_final']);
            $query = $query->andWhere('nfse_data_hora')->between($forms['data_inicial'],$forms['data_final']);
        }
        if($forms['emitente'] != ''){
            $queryPaginator = $queryPaginator->andWhere('nfse_emitente')->like('%'.$forms['emitente'].'%');
            $query = $query->andWhere('nfse_emitente')->like('%'.$forms['emitente'].'%');
        }
        if($forms['chave'] != ''){
            $queryPaginator = $queryPaginator->andWhere('nfse_chave')->is($forms['chave']);
            $query = $query->andWhere('nfse_chave')->is($forms['chave']);
        }
        if(empty($data['sort'])){
            $data['sort'] = 'nfse_id';
        }
        if(empty($data['sort_dir'])){
            $data['sort_dir'] = 'desc';
        }

        $resPaginator = $queryPaginator->select()->all();
        $result = $query->orderBy($data['sort'], $data['sort_dir'])
            ->limit($data['size'])
            ->offset($start)
            ->select()
            ->all();


        if($result){
            $page = ceil(count($resPaginator) / $max);
            $rows['last_page'] = $page;
            $rows['quantify'] = count($resPaginator);
            foreach($result as $r){
                $r->nfse_data_hora = format_datetime_br($r->nfse_data_hora);

                $r->nfse_valor_servico = 'R$ '.format_money($r->nfse_valor_servico);
                $rows['data'][] = $r;
            }

            echo json_encode($rows);
            return;
        }else{
            $rows['last_page'] = '0';
            $rows['quantify'] = '0';
            echo json_encode($rows);
            return;
        }
    }

    public function downloadZip(array $data)
    {
        if(in_array('', $data)){
            $this->call(
                '200',
                'Ops',
                '<button type="button" class="btn btn-secondary" data-dismiss="modal">Fechar</button>',
                "error",
                "Existem campos em branco"
            )->back(["count" => 0]);
            return;
        }

        $explode_file = explode(',', $data['id_doc']);


        $resultDoc = $this->db()->from('nfse')
            ->join('company', function($join){
                $join->on('company_id', 'nfse_id_company');
            })
            ->where('company_id_user')->is(ID_LOG)
            ->andWhere('nfse_id')->in($explode_file)
            ->select()
            ->all();

        if($resultDoc){
            $randFolder = rand(100000,999999);
            if(mkdir('shared/temp/'.$randFolder.'/', 0777, true)){
                $zip = new \ZipArchive();
                $arqZip = 'shared/zipex/'.$randFolder.'.zip';
                $zip->open($arqZip, \ZipArchive::CREATE);
                foreach($resultDoc as $r){
                    $nameFile = $r->nfse_chave.'-nfse.xml';
                    $decoded_file_data = base64_decode($r->nfse_xml);
                    file_put_contents('shared/temp/'.$randFolder.'/'.$nameFile, $decoded_file_data);

                    $zip->addFile('shared/temp/'.$randFolder.'/'.$nameFile, $nameFile);
                }
                $zip->close();


                foreach($resultDoc as $r){
                    $nameFile = $r->nfse_chave.'-nfse.xml';
                    unlink('shared/temp/'.$randFolder.'/'.$nameFile);
                }

                rmdir('shared/temp/'.$randFolder.'/');
                $linkZip = '<a href="../'.$arqZip.'" class="btn btn-brown" download>BAIXAR OS ARQUIVOS</a>';

                $this->call(
                    '200',
                    'Parabéns',
                    '<button type="button" class="btn btn-secondary" data-dismiss="modal">Fechar</button>',
                    "ok",
                    "Documento processado com sucesso"
                )->back(["button" => $linkZip]);
                return;
            }

            $this->call(
                '200',
                'Ops',
                '<button type="button" class="btn btn-secondary" data-dismiss="modal">Fechar</button>',
                "error",
                "Sem informações"
            )->back(["count" => 0]);
            return;
        }

        $this->call(
            '200',
            'Ops',
            '<button type="button" class="btn btn-secondary" data-dismiss="modal">Fechar</button>',
            "error",
            "Não existem arquivos"
        )->back(["count" => 0]);
        return;
    }

    public function danfe(array $data)
    {
        if(in_array('', $data)){
            $this->call(
                '200',
                'Ops',
                '<button type="button" class="btn btn-secondary" data-dismiss="modal">Fechar</button>',
                "error",
                "Existem campos em branco"
            )->back(["count" => 0]);
            return;
        }

        $explode_file = explode(',', $data['id_doc']);




        $resultDoc = $this->db()->from('nfse')
            ->join('company', function($join){
                $join->on('company_id', 'nfse_id_company');
            })
            ->join('certificate', function($join){
                $join->on('certificate_id_company', 'company_id');
            })
            ->where('company_id_user')->is(ID_LOG)
            ->andWhere('nfse_id')->in($explode_file)
            ->select()
            ->all();



        if($resultDoc){
            $randFolder = rand(100000,999999);
            if(mkdir('shared/temp/'.$randFolder.'/', 0777, true)){
                $zip = new \ZipArchive();
                $arqZip = 'shared/zipex/'.$randFolder.'.zip';
                $zip->open($arqZip, \ZipArchive::CREATE);
                foreach($resultDoc as $r){
                    $nameFile = $r->nfse_chave.'-nfse.pdf';
                    $curl = curl_init();

                    curl_setopt_array($curl, array(
                        CURLOPT_URL => 'https://sefin.nfse.gov.br/sefinnacional/danfse/'.$r->nfse_chave,
                        CURLOPT_RETURNTRANSFER => true,
                        CURLOPT_ENCODING => '',
                        CURLOPT_MAXREDIRS => 10,
                        CURLOPT_TIMEOUT => 0,
                        CURLOPT_FOLLOWLOCATION => true,
                        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                        CURLOPT_CUSTOMREQUEST => 'GET',
                        CURLOPT_SSLCERT => realpath('certificado.pfx'),
                        CURLOPT_SSLCERTPASSWD => '123456',
                        CURLOPT_SSLCERTTYPE => 'P12',
                    ));

                    $response = curl_exec($curl);

                    curl_close($curl);
                    file_put_contents('shared/temp/'.$randFolder.'/'.$nameFile, $response);

                    $zip->addFile('shared/temp/'.$randFolder.'/'.$nameFile, $nameFile);
                }
                $zip->close();


                foreach($resultDoc as $r){
                    $nameFile = $r->nfse_chave.'-nfse.pdf';
                    unlink('shared/temp/'.$randFolder.'/'.$nameFile);
                }

                rmdir('shared/temp/'.$randFolder.'/');
                $linkZip = '<a href="../'.$arqZip.'" class="btn btn-brown" download>BAIXAR OS ARQUIVOS</a>';

                $this->call(
                    '200',
                    'Parabéns',
                    '<button type="button" class="btn btn-secondary" data-dismiss="modal">Fechar</button>',
                    "ok",
                    "Documento processado com sucesso"
                )->back(["button" => $linkZip]);
                return;
            }


            $this->call(
                '200',
                'Ops',
                '<button type="button" class="btn btn-secondary" data-dismiss="modal">Fechar</button>',
                "error",
                "Sem informações"
            )->back(["count" => 0]);
            return;
        }

        $this->call(
            '200',
            'Ops',
            '<button type="button" class="btn btn-secondary" data-dismiss="modal">Fechar</button>',
            "error",
            "Não existem arquivos"
        )->back(["count" => 0]);
        return;
    }
}
