<?php
class RemessaPgto{

  private $empresa = false;

  private $remessa_numero;
  private $remessa_arq_nome;
  private $remessa_txt_completo;

  private $lote_qtd = 1;
  private $lote_numero = 1;

  private $registros_linha = 1;
  private $registros_qtd;
  private $registros;
  private $registros_valor_total;

  public function __construct($empresa, $registros){
    global $bd;
    $this->bd = $bd;

    $this->registros = $registros;
    $this->registros_qtd = count($registros);

    $this->empresa($empresa);
    $this->remessaInfs();
    $this->gerarArquivo();
  }

  public function empresa($empresa){
    $empresas = array(
      "pw" => array(
        "id"=>1,
        "razao"=>"App Poker Web Sistemas Ltda",
        "cnpj"=>"25131762000158",
        "banco"=>"748",
        "agencia"=>"0710",
        "dv_agencia"=>" ",
        "conta"=>"21486",
        "dv_conta"=>"1",
        "end"=>'RUA DAS GARDENIAS',
        "end_complemento"=>'VILA FLORATTA',
        "end_numero"=>'386',
        "end_cidade"=>'FOZ DO IGUACU',
        "end_uf"=>'PR',
        "end_CEP"=>['85853','673'],
      ),
      "gid" => array(
        "id"=>1,
        "razao"=>"GID INTERMEDIAÇÕES E RESERVAS",
        "cnpj"=>"44249060000118",
        "banco"=>"748",
        "agencia"=>"0710",
        "dv_agencia"=>"2",
        "conta"=>"27901",
        "dv_conta"=>"8",
        "end"=>'RUA DAS GARDENIAS',
        "end_complemento"=>'VILA FLORATTA',
        "end_numero"=>'386',
        "end_cidade"=>'FOZ DO IGUACU',
        "end_uf"=>'PR',
        "end_CEP"=>['85853','673'],
      ),
      "gid_int" => array(
        "id"=>1,
        "razao"=>"GID INTERMEDIAÇÕES E RESERVAS",
        "cnpj"=>"44249060000118",
        "banco"=>"748",
        "agencia"=>"0710",
        "dv_agencia"=>"2",
        "conta"=>"28027",
        "dv_conta"=>"9",
        "end"=>'RUA DAS GARDENIAS',
        "end_complemento"=>'VILA FLORATTA',
        "end_numero"=>'386',
        "end_cidade"=>'FOZ DO IGUACU',
        "end_uf"=>'PR',
        "end_CEP"=>['85853','673'],
      ),
    );
    $this->empresa = $empresas[$empresa];
  }

  private function remessaInfs(){
    $sql = $this->bd->getConexao()->prepare('
    SELECT
      count(distinct id) as qtd_total,
      CASE WHEN emissao = :data THEN 1 ELSE 0 END as qtd_dia
    FROM remessas_pgto');
    $sql->bindValue(':data', date("Y-m-d"), PDO::PARAM_STR);
    if($sql->execute()){$remessas = $sql->fetch(PDO::FETCH_ASSOC);}

    // Número sequencia da remessa
    $this->remessa_numero = $remessas['qtd_total']+1;

    // Nome para o arquivo, baseado na quantidade de emissões do dia
    $this->remessa_arq_nome =
      '3ALF'.
      $this->left_0(date("d"),2).
      //$this->mesesCod(date("m")).
      $this->left_0($remessas['qtd_dia'],2).
      '.REM';
  }

  // Montagem do arquivo
  // ************************************************
  private function gerarArquivo(){
    $header_arq = $this->txtHeaderArq();
    $header_lote = $this->txtHeaderLote();
    $registros = $this->txtRegistros();
    $trailer_lote = $this->txtTrailerLote();
    $trailer_arq = $this->txtTrailerArq();

    $this->remessa_txt_completo = $header_arq.$header_lote.$registros.$trailer_lote.$trailer_arq;

    if(!$handle = fopen($this->remessa_arq_nome, 'w+')){}
    if(fwrite($handle, "$this->remessa_txt_completo")===FALSE){}
    fclose($handle);

    //echoPre($this->remessa_arq_nome);
    $this->download($this->remessa_arq_nome);
  }

  private function txtHeaderArq(){
    $txt  = $this->empresa['banco'];                      // Cod. do banco
    $txt .= $this->cr(4,"zeros");                         // Cod. do lote
    $txt .= '0';                                          // Tipo de registro
    $txt .= $this->cr(9,"brancos");                       //
    $txt .= '2';                                          // Tipo de inscrição do beneficiario : um se pessoa fisico (1) ou juridica (2)
    $txt .= $this->left_0($this->empresa['cnpj'],14);     // Nº de Inscrição do Beneficiario cpf ou cnpj da escola emissora do boleto
    $txt .= $this->cr(20,"brancos");                      // Uso exclusivo do banco // TODO
    $txt .= $this->left_0($this->empresa['agencia'],5);   // Cod. da agencia mantenedora da conta
    $txt .= $this->cr(1,"brancos");                       // Digito verificador da agencia
    $txt .= $this->left_0($this->empresa['conta'],12);    // Cod. do benefici�rio fornecido pelo banco - N� do cedente
    $txt .= $this->empresa['dv_conta'];                   // Digito verificador da conta
    $txt .= $this->cr(1,"brancos");                       //
    $txt .= $this->right_x($this->empresa['razao'],30);   // Nome da empresa
    $txt .= $this->right_x('SICREDI',30);                 // Nome do banco
    $txt .= $this->cr(10,"brancos");                      //
    $txt .= '1';                                          // Cod. (1) = Remessa ou (2) = Retorno.
    $txt .= date('dmY');;                                 // Data da geracao arquivo
    $txt .= date('His');                                  // Hora da geracao arquivo
    $txt .= $this->left_0($this->remessa_numero,6);       // Sequencial do arquivo um numero novo para cada arquivo de remessa que for gerado
    $txt .= '082';                                        // Versao
    $txt .= '01600';                                      // Densidade de Gravacao do Arquivo
    $txt .= $this->cr(20,"brancos");                      //
    $txt .= $this->cr(20,"brancos");                      // Observação
    $txt .= $this->cr(29,"brancos");                      //
    $txt .= chr(13).chr(10);                              // QUEBRA DE LINHA
    return $txt;
  }

  private function txtHeaderLote(){
    $txt  = $this->empresa['banco'];                                // Cod. do banco
    $txt .= $this->left_0($this->lote_numero,4);                    // Cod. do lote
    $txt .= '1';                                                    // Tipo de registro
    $txt .= 'C';                                                    // Tipo de Operação
    $txt .= '20';                                                   // Serviço (20 - pagamento fornecedor)
    $txt .= '45';                                                   // Forma de lançamento (45 pix / 41 ted)
    $txt .= '042';                                                  // Layout do Lote
    $txt .= $this->cr(1,"brancos");                                 //
    $txt .= '2';                                                    // Tipo de inscrição do beneficiario : um se pessoa fisico (1) ou juridica (2)
    $txt .= $this->left_0($this->empresa['cnpj'],14);               // Nº de Inscrição do Beneficiario cpf ou cnpj da escola emissora do boleto
    $txt .= $this->cr(20,"brancos");                                // Uso exclusivo do banco
    $txt .= $this->left_0($this->empresa['agencia'],5);             // Cod. da agencia mantenedora da conta
    $txt .= $this->cr(1,"brancos");                                 // Digito verificador da agencia
    $txt .= $this->left_0($this->empresa['conta'],12);              // Cod. do benefici�rio fornecido pelo banco - N� do cedente
    $txt .= $this->empresa['dv_conta'];                             // Digito verificador da conta
    $txt .= $this->cr(1,"brancos");                                 //
    $txt .= $this->right_x($this->empresa['razao'],30);             // Nome da empresa
    $txt .= $this->cr(40,"brancos");                                //
    $txt .= $this->right_x($this->empresa['end'],30);               // Empresa: Endereço
    $txt .= $this->left_0($this->empresa['end_numero'],5);          // Empresa: Número
    $txt .= $this->right_x($this->empresa['end_complemento'],15);   // Empresa: Complemento
    $txt .= $this->right_x($this->empresa['end_cidade'],20);        // Empresa: Cidade
    $txt .= $this->left_0($this->empresa['end_CEP'][0],5);          // Empresa: CEP 1
    $txt .= $this->left_0($this->empresa['end_CEP'][1],3);          // Empresa: CEP 2
    $txt .= $this->left_0($this->empresa['end_uf'],2);              // Empresa: UF
    $txt .= $this->cr(8,"brancos");                                 //
    $txt .= $this->cr(10,"brancos");                                //
    $txt .= chr(13).chr(10);                                        // QUEBRA DE LINHA
    return $txt;
  }

  private function txtRegistros(){
    $txt = '';
    // Roda todos os registros
    foreach($this->registros as $l){

      // SEGMENTO A
      $txt .= $this->empresa['banco'];                    // Cod. Banco
      $txt .= $this->left_0($this->lote_numero,4);        // Lote de serviço
      $txt .= '3';                                        // tipo de registro. Equivalente a detalhe de lote. preencher '3'
      $txt .= $this->left_0($this->registros_linha,5);    // N Sequencial do Registro no Lote
      $txt .= 'A';                                        // Cod. Segmento do Registro Detalhe
      $txt .= '0';                                        // Tipo de movimento (0 inclusao / 9 exclusao)
      $txt .= '00';                                       // Código de instrução para movimento (00 inclusao / 99 exclusao)
      // favorecido
      $txt .= '009';                                                    // Código da câmara (009 pix / 018 ted)
      $txt .= $this->cr(3,"zeros");                                     // Código do banco do favorecido
      $txt .= $this->cr(5,"zeros");                                     // Ag. mantenedora da conta
      $txt .= $this->cr(1,"zeros");                                     // Dígito verificador da agência
      $txt .= $this->cr(12,"zeros");                                    // Número da conta corrente
      $txt .= $this->cr(1,"zeros");                                     // Dígito verificador da conta
      $txt .= $this->cr(1,"brancos");                                   // Dígito verificador da ag./conta
      $txt .= $this->right_x($this->remover_acentos($l['nome']),30);    // Nome do favorecido
      $txt .= $this->cr(20,"brancos");                                  // Nº do docum. atribuído p/ empresa (controle interno da empresa)
      // credito
      $txt .= date('dmY');                                // Data do pagamento
      $txt .= 'BRL';                                      // Moeda
      $txt .= $this->cr(15,"zeros");                      // Quantidade da moeda (10 e 5 decimal)
      $txt .= $this->left_0($l['valor'],15);              // Valor do pagamento (13 e 2 decimal)
      $txt .= $this->cr(20,"brancos");                    //
      $txt .= $this->cr(8,"zeros");                       // Data real da efetivação pagto (não usado na remessa)
      $txt .= $this->cr(15,"zeros");                      // Valor real da efetivação do pagto (13 e 2 decimal) (não usado na remessa)
      $txt .= $this->cr(40,"brancos");                    //
      // complemento
      $txt .= $this->cr(2,"brancos");                     // Código finalidade DOC
      $txt .= $this->cr(5,"brancos");                     // Código finalidade TED
      $txt .= $this->cr(2,"brancos");                     // Código finalidade complementar
      $txt .= $this->cr(3,"brancos");                     //
      $txt .= $this->cr(1,"zeros");                       // Zeros
      $txt .= $this->cr(10,"brancos");                    //
      $txt .= chr(13).chr(10);                            // QUEBRA DE LINHA

      $this->registros_linha ++;
      $this->registros_valor_total += $l['valor'];

      // SEGMENTO B
      $txt .= $this->empresa['banco'];                    // Cod. Banco
      $txt .= $this->left_0($this->lote_numero,4);        // Lote de serviço
      $txt .= '3';                                        // tipo de registro. Equivalente a detalhe de lote. preencher '3'
      $txt .= $this->left_0($this->registros_linha,5);    // N Sequencial do Registro no Lote
      $txt .= 'B';                                        // Cod. Segmento do Registro Detalhe
      $txt .= $this->right_x($l['pix_tipo'],3);           // Tipo de chave pix (01 telefone / 02 email / 03 cpf/cnpj / 04 aleatoria)
      $txt .= $l['doc_tipo'];                             // Tipo de inscrição (pessoa fisico (1) ou juridica (2))
      $txt .= $this->left_0($l['doc_numero'],14);         // Nº de Inscrição do Beneficiario cpf ou cnpj
      $txt .= $this->cr(30,"brancos");                    // Informações 10
      $txt .= $this->cr(65,"brancos");                    // Informações 11 entre usuários (mensagem identificação para quem vai receber)
      $txt .= $this->right_x($l['pix_chave'],99);         // Informações 12 (chave pix)
      $txt .= $this->cr(6,"zeros");                       //
      $txt .= $this->cr(8,"zeros");                       //
      $txt .= chr(13).chr(10);                            // QUEBRA DE LINHA

      $this->registros_linha ++;
    }
    return $txt;
  }

  private function txtTrailerLote(){
    $txt  = $this->empresa['banco'];                            // Cod. do banco
    $txt .= $this->left_0($this->lote_numero,4);                // Cod. do lote
    $txt .= '5';                                                // Tipo de registro
    $txt .= $this->cr(9,"brancos");                             //
    $txt .= $this->left_0($this->registros_qtd,6);              // Quantidade de registros no lote
    $txt .= $this->left_0($this->registros_valor_total,16);     // Valor total do lote
    $txt .= $this->cr(13,"zeros");                              // Quantidade total de moedas
    $txt .= $this->cr(6,"zeros");                               // Número aviso de débito
    $txt .= $this->cr(165,"brancos");                           //
    $txt .= $this->cr(10,"brancos");                            //
    $txt .= chr(13).chr(10);                                    // QUEBRA DE LINHA
    return $txt;
  }

  private function txtTrailerArq(){
    $qtd_reg_arq = (100*3)+4;

    $txt  = $this->empresa['banco'];                    // COD. DO BANCO
    $txt .= '9999';                                     // lote de serviço. Preencher '9999'
    $txt .= '9';                                        // Tipo de registro. Preencher '9'
    $txt .= $this->cr(9,"brancos");                     //
    $txt .= $this->left_0($this->lote_qtd,6);           // Quantidade de lotes do arquivo
    $txt .= $this->left_0($this->registros_qtd,6);      // Quantidade de registros no arquivo
    $txt .= $this->cr(6,"zeros");                       // Espacos
    $txt .= $this->cr(205,"brancos");                   // Espacos
    return $txt;
  }


  // Funções auxiliares
  // ************************************************

  function download($arquivo){
    header("Content-Type: application/force-download");
    header("Content-Type: application/octet-stream;");
    header("Content-Length:".filesize($arquivo));
    header("Content-disposition: attachment; filename=".$arquivo);
    header("Pragma: no-cache");
    header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
    header("Expires: 0");
    readfile($arquivo);
    flush();
  }

  function remover_acentos($string){
    return preg_replace(array("/(á|à|ã|â|ä)/","/(Á|À|Ã|Â|Ä)/","/(é|è|ê|ë)/","/(É|È|Ê|Ë)/","/(í|ì|î|ï)/","/(Í|Ì|Î|Ï)/","/(ó|ò|õ|ô|ö)/","/(Ó|Ò|Õ|Ô|Ö)/","/(ú|ù|û|ü)/","/(Ú|Ù|Û|Ü)/","/(ñ)/","/(Ñ)/","/(ç)/","/(Ç)/","/(´)/","/(º)/","/(ª)/"),explode(" ","a A e E i I o O u U n N c C"),$string);
  }
  function left_0($palavra,$limite){ return str_pad($palavra, $limite, "0", STR_PAD_LEFT); }
  function right_0($palavra,$limite){ return str_pad($palavra, $limite, "0", STR_PAD_RIGHT); }
  function right_x( $palavra, $limite ){
    $var = str_pad( $palavra, $limite, " ", STR_PAD_RIGHT );
    $var = $this->remover_acentos( $var );
    if( strlen( $palavra ) >= $limite ){
      $var = substr( $palavra, 0, $limite );
    }
    $var = strtoupper( $var );// converte em letra maiuscula
    return $var;
  }
  function cr($seq_linhant,$tipo){
    if($tipo == "zeros"){
      $space = '';
      for($seq_linha = 1; $seq_linha <= $seq_linhant; $seq_linha++){
        $space .= '0';
      }
    } else if($tipo == "brancos"){
      $space = '';
      for($seq_linha = 1; $seq_linha <= $seq_linhant; $seq_linha++){
        $space .= ' ';
      }
    }
    return $space;
  }
  function mesesCod($mes){
    if($mes==10){ $mes_echo = "O";}
    else if($mes==11){ $mes_echo = "N";}
    else if($mes==12){ $mes_echo = "D";}
    return $mes;
  }

}