<?php
/**
* PDF - Nota Fiscal do Consumidor
*
*/
	define('_VALID_PHP', true);
	header('Content-Type: text/html; charset=utf-8');

	require_once('init.php');
	require_once __DIR__ . '/vendor/autoload.php';
	use Ramsey\Uuid\Uuid;

	if (!$usuario->is_Todos())
		redirect_to("login.php");

	$id = get('id');
	$dg = get('debug');
	$ctg = get('contingencia');
	$ngd = get('negada');

	$debug = ($dg == 1) ? true : false;
	$reprocessarContingencia = ($ctg == 1) ? true : false;
	$reprocessarNegada = ($ngd == 1) ? true : false;

	$row_venda = Core::getRowById("vendas", $id);
	$row_empresa = Core::getRowById("empresa", $row_venda->id_empresa);

	if (!empty($row_venda->uuid)) {
		$uuid_venda = $row_venda->uuid;
	} else {
		$uuid_venda = Uuid::uuid4();
		$data = array(
			'uuid' => $uuid_venda,
		);
		$db->update("vendas", $data, "id=" . $id);
	}

	if ($core->emissor_producao) {
		$ambiente = 'producao'; //'Producao' ou 'Homologacao'
		$idExterno = ($row_empresa->versao_emissao==0) ? 'nfce-'.$id : 'nfce'.$row_empresa->versao_emissao.'-'.$id;
	} else {
		echo "</br>--- --- --- --- AMBIENTE DE HOMOLOGAÇÃO --- --- --- ---</br>";
		$ambiente = 'homologacao'; //'Producao' ou 'Homologacao'
		$idExterno = ($row_empresa->versao_emissao==0) ? 'Hnfce-'.$id : 'Hnfce'.$row_empresa->versao_emissao.'-'.$id;
	}

	$data_venda = exibedataHora($row_venda->data_venda);
	$valor_total = floatval($row_venda->valor_total);
	$valor_desconto = floatval($row_venda->valor_desconto);
	$valor_pago = floatval($row_venda->valor_pago);
	$valor_desconto = 0;
	$atendente = $row_venda->usuario;
	$cnpj_emissor = $row_empresa->cnpj;
	$cnpj_contador = $row_empresa->cnpj_contador;

	$data_impressao = date('Ymd');

	try	{
		if($row_venda->fiscal && !$reprocessarNegada) {
			$retorno = $cadastro->getConsultarNFC($cnpj_emissor,$idExterno);
			$dados_emissao = $retorno['data'];

			if($row_venda->chaveacesso && !$reprocessarContingencia) {
				$data_emissao = $dados_emissao['data_emissao'];
				$numero_nota = $dados_emissao['numero'] . "-". $dados_emissao['serie'];
				$status_emissao = ($dados_emissao['estado_emissao'] == "autorizado") ? "Autorizada": ucfirst($dados_emissao['estado_emissao']);
				$links = $dados_emissao['links'];

				//Este procedimento de subtrair três horas da data de emissão é necessário pois a API gera um horário com três horas a mais no registro
				//das notas. Mas na danfe, a própria api gerar o horário correto e na sefaz o horário também vai correto.
				$dataRetornoAPI = new DateTime($data_emissao);
				$dataRetornoAPI->sub(new DateInterval('PT03H00S'));
				$data_emissao = $dataRetornoAPI->format('Y-m-d H:i:s');

				$data = array(
					'id_emissao' => $dados_emissao['id'],
					'numero_nota' => $numero_nota,
					'numero' => $dados_emissao['numero'],
					'serie' => $dados_emissao['serie'],
					'chaveacesso' => $dados_emissao['chave_acesso'],
					'link_danfe' => $links['pdf'],
					'link_download_xml' => $links['xml'],
					'status_enotas' => $status_emissao,
					'motivo_status' => "NFC-e emitida com sucesso",
					'contingencia' => ($dados_emissao['contingencia']) ? 1 : 0,
					'data_emissao' => $data_emissao,
					'fiscal' => (empty($dados_emissao['chave_acesso'])) ? 0 : 1,
					'usuario' => session('nomeusuario'),
					'data' => "NOW()"
				);
				$db->update("vendas", $data, "id=" . $id);

				$pdf = $links['pdf'];
				header("Location: $pdf");
			} else {
				$data_emissao = $dados_emissao['data_emissao'];
				$numero_nota = $dados_emissao['numero'] . "-". $dados_emissao['serie'];
				$status_emissao = ($dados_emissao['estado_emissao'] == "autorizado") ? "Autorizada": ucfirst($dados_emissao['estado_emissao']);
				$motivo_status = ( $retorno['message'] == "NFC-e encontrada") ? "NFC-e emitida com sucesso" :  json_decode($retorno['message']);
				$links = $dados_emissao['links'];

				//Este procedimento de subtrair três horas da data de emissão é necessário pois a API gera um horário com três horas a mais no registro
				//das notas. Mas na danfe, a própria api gerar o horário correto e na sefaz o horário também vai correto.
				$dataRetornoAPI = new DateTime($data_emissao);
				$dataRetornoAPI->sub(new DateInterval('PT03H00S'));
				$data_emissao = $dataRetornoAPI->format('Y-m-d H:i:s');

				if($dados_emissao['estado_emissao'] == "autorizado") {
					if(intval($dados_emissao['numero']) > 0) {
						$data = array(
							'id_emissao' => $dados_emissao['id'],
							'numero_nota' => $numero_nota,
							'numero' => $dados_emissao['numero'],
							'serie' => $dados_emissao['serie'],
							'chaveacesso' => $dados_emissao['chave_acesso'],
							'link_danfe' => $links['pdf'],
							'link_download_xml' => $links['xml'],
							'status_enotas' => $status_emissao,
							'motivo_status' => $motivo_status,
							'contingencia' => ($dados_emissao['contingencia']) ? 1 : 0,
							'data_emissao' => $data_emissao,
							'fiscal' => (empty($dados_emissao['chave_acesso'])) ? 0 : 1,
							'usuario' => session('nomeusuario'),
							'data' => "NOW()"
						);
						$db->update("vendas", $data, "id=" . $id);

						$pdf = $links['pdf'];
						header("Location: $pdf");
					}
				} else {
					if(intval($dados_emissao['numero']) > 0) {
						$data = array(
							'id_emissao' => $dados_emissao['id'],
							'numero_nota' => $numero_nota,
							'numero' => $dados_emissao['numero'],
							'serie' => $dados_emissao['serie'],
							'chaveacesso' => $dados_emissao['chave_acesso'],
							'link_danfe' => $links['pdf'],
							'link_download_xml' => $links['xml'],
							'status_enotas' => $status_emissao,
							'motivo_status' => $motivo_status,
							'contingencia' => ($dados_emissao['contingencia']) ? 1 : 0,
							'data_emissao' => $data_emissao,
							'fiscal' => (empty($dados_emissao['chave_acesso'])) ? 0 : 1,
							'usuario' => session('nomeusuario'),
							'data' => "NOW()"
						);
						$db->update("vendas", $data, "id=" . $id);
					}

					echo "</br>--- status: ".$status_emissao." ---</br>";
					//Este procedimento de subtrair três horas da data de emissão é necessário pois a API gera um horário com três horas a mais no registro
					//das notas. Mas na danfe, a própria api gerar o horário correto e na sefaz o horário também vai correto.
					$dataRetornoAPI = new DateTime($data_emissao);
					$dataRetornoAPI->sub(new DateInterval('PT03H00S'));
					$data_emissao = $dataRetornoAPI->format('Y-m-d H:i:s');
					echo "</br>--- data_emissao: ".exibedata($data_emissao)." ---</br>";
				}
			}
		} else {
			$array_itens = array();
			$retorno_row = $cadastro->getItemVenda($id);

			if($retorno_row){
				$count_itens = 0;

				foreach ($retorno_row as $exrow) {
					$icms_cst = ($exrow->icms_cst > 0) ? $exrow->icms_cst : '102';
					$icms_cst = ($exrow->icms_cst == '000' || $exrow->icms_cst == '00') ? $exrow->icms_cst : $icms_cst;
					$icms_percentual = ($exrow->icms_percentual > 0) ? $exrow->icms_percentual : 17.72;
					$icms_percentual = floatval($icms_percentual);
					$cst = intval($icms_cst);

					if($cst == 103 or $cst == 203 or $cst == 300 or $cst == 400) {
						$icms_percentual = 0;
					}

					$codigo = ($exrow->codigo) ? $exrow->codigo : $exrow->id_produto;
					$ncm = limparNumero($exrow->ncm);
					$quantidade = floatval($exrow->quantidade);
					$descontos = floatval($exrow->valor_desconto);
					$outrasDespesas = floatval($exrow->valor_despesa_acessoria);
					$valor_prd = floatval($exrow->valor);
					$cest = limparNumero($exrow->cest);

					if($exrow->anp) {
						$count_itens++;
						$array_itens[] = array(
							'descricao' => $exrow->produto,
							'codigo' => $codigo,
							'quantidade' => $quantidade,
							'valor_unitario' => $valor_prd,
							'valor_desconto' => $descontos,
							'valor_acrescimo' => $outrasDespesas,
							'unidade_venda' => $exrow->unidade,
							'ncm' => $ncm,
							'cfop' => $exrow->cfop,
							'cest' => $cest,
							'cst_csosn' => $icms_cst,
							'cst_pis' => $exrow->pis_cst,
							'cst_cofins' => $exrow->cofins_cst,
							'cst_ipi' => ($exrow->ipi_saida_codigo == 0) ? "" : $exrow->ipi_saida_codigo,

							'combustivel' => array(
								'codigoProdutoANP' => $exrow->anp,
								'percentualGasNatural' => 100,
								'valorDePartida' => $exrow->valor_partida,
								'codif' => null,
								'quantidadeFaturadaTempAmbiente' => $exrow->quantidade,
								'ufConsumo' => 'MG',
								'cide' => array(
									'quantidadeBaseCalculo' => $exrow->quantidade,
									'valorAliquota' => 0.0000,
									'valor' => $valor_prd
								)
							)
						);

						if ($exrow->anp != '210203001'){
							unset($array_itens[$count_itens-1]['combustivel']['percentualGasNatural']);
						}

						if ($exrow->pis_cst == ''){
							unset($array_itens[$count_itens-1]['impostos']['pis']);
						}elseif($exrow->pis_aliquota == 0){
							unset($array_itens[$count_itens-1]['impostos']['pis']['porAliquota']);
						}

						if ($exrow->cofins_cst== ''){
							unset($array_itens[$count_itens-1]['impostos']['cofins']);
						}elseif($exrow->cofins_aliquota == 0){
							unset($array_itens[$count_itens-1]['impostos']['cofins']['porAliquota']);
						}

						if ($exrow->ipi_saida_codigo == 0){
							unset($array_itens[$count_itens-1]['impostos']['ipi']);
						}elseif($exrow->ipi_cst == 0){
							unset($array_itens[$count_itens-1]['impostos']['ipi']['porAliquota']);
						}
					} elseif($cest) {
						$count_itens++;
						$array_itens[] = array(
							'descricao' => $exrow->produto,
							'codigo' => $codigo,
							'quantidade' => $quantidade,
							'valor_unitario' => $valor_prd,
							'valor_desconto' => $descontos,
							'valor_acrescimo' => $outrasDespesas,
							'unidade_venda' => $exrow->unidade,
							'ncm' => $ncm,
							'cfop' => $exrow->cfop,
							'cest' => $cest,
							'cst_csosn' => $icms_cst,
							'cst_pis' => $exrow->pis_cst,
							'cst_cofins' => $exrow->cofins_cst,
							'cst_ipi' => ($exrow->ipi_saida_codigo == 0) ? "" : $exrow->ipi_saida_codigo,
						);

						if ($exrow->pis_cst == ''){
							unset($array_itens[$count_itens-1]['impostos']['pis']);
						}elseif($exrow->pis_aliquota == 0){
							unset($array_itens[$count_itens-1]['impostos']['pis']['porAliquota']);
						}

						if ($exrow->cofins_cst== ''){
							unset($array_itens[$count_itens-1]['impostos']['cofins']);
						}elseif($exrow->cofins_aliquota == 0){
							unset($array_itens[$count_itens-1]['impostos']['cofins']['porAliquota']);
						}

						if ($exrow->ipi_saida_codigo == 0){
							unset($array_itens[$count_itens-1]['impostos']['ipi']);
						}elseif($exrow->ipi_cst == 0){
							unset($array_itens[$count_itens-1]['impostos']['ipi']['porAliquota']);
						}
					} else {
						$count_itens++;
						$array_itens[] = array(
							'descricao' => $exrow->produto,
							'codigo' => $codigo,
							'quantidade' => $quantidade,
							'valor_unitario' => $valor_prd,
							'valor_desconto' => $descontos,
							'valor_acrescimo' => $outrasDespesas,
							'unidade_venda' => $exrow->unidade,
							'ncm' => $ncm,
							'cfop' => $exrow->cfop,
							'cst_csosn' => $icms_cst,
							'cst_pis' => $exrow->pis_cst,
							'cst_cofins' => $exrow->cofins_cst,
							'cst_ipi' => ($exrow->ipi_saida_codigo == 0) ? "" : $exrow->ipi_saida_codigo,
						);

						if ($exrow->pis_cst == ''){
							unset($array_itens[$count_itens-1]['impostos']['pis']);
						}elseif($exrow->pis_aliquota == 0){
							unset($array_itens[$count_itens-1]['impostos']['pis']['porAliquota']);
						}

						if ($exrow->cofins_cst== ''){
							unset($array_itens[$count_itens-1]['impostos']['cofins']);
						}elseif($exrow->cofins_aliquota == 0){
							unset($array_itens[$count_itens-1]['impostos']['cofins']['porAliquota']);
						}

						if ($exrow->ipi_saida_codigo == 0){
							unset($array_itens[$count_itens-1]['impostos']['ipi']);
						}elseif($exrow->ipi_cst == 0){
							unset($array_itens[$count_itens-1]['impostos']['ipi']['porAliquota']);
						}
					}
				}
				unset($exrow);
			}

			$array_pagamento = array();
			$retorno_row = $cadastro->getFinanceiroVenda($id);

			if($retorno_row){
				foreach ($retorno_row as $exrow) {
					$tipo = pagamentoNFCSigesis($exrow->categoria);
					$array_pagamento[] = array(
						'tipo' => $tipo,
						'valor' => $exrow->valor_pago,
						'cartao_bandeira' => '',
						'cartao_tipo_integracao' => '',
						'cartao_integracao_cnpj' => '',
						'cartao_autorizacao' => ''
					);
				}
				unset($exrow);
			}

			$data_emissao = "NOW()";
			$nota_simples = array(
				'id_externo' => $idExterno,
				'cnpj' => $cnpj_emissor,
				'ambiente' => $ambiente, //'Producao' ou 'Homologacao'
				'natureza_operacao' => 'venda_consumidor_final',
				'contingencia' => false,
				'itens' => $array_itens,
				'pagamentos' => $array_pagamento
			);

			$cadastro_valido = true;

			if($row_venda->id_cadastro) {
				$row_cadastro = Core::getRowById("cadastro", $row_venda->id_cadastro);

				if(valida_cpf_cnpj($row_cadastro->cpf_cnpj)) {
					$tipo = '';

					if($row_cadastro->tipo == 1) {
						$tipo = 'J';
					} elseif($row_cadastro->tipo == 2) {
						$tipo = 'F';
					}

					$array_cliente = array(
						'nome' => $row_cadastro->nome, 	//opcional
						'razao_social' => $row_cadastro->razao_social,
						'cpf_cnpj' => limparCPF_CNPJ($row_cadastro->cpf_cnpj), //opcional
						'email' => $row_cadastro->email, 	//opcional
						'telefone' => limparNumero($row_cadastro->telefone), //opcional
						'rua' => $row_cadastro->endereco, //opcional
						'numero' => $row_cadastro->numero, //opcional
						'bairro' => $row_cadastro->bairro, //opcional
						'cidade' => $row_cadastro->cidade, //opcional
						'uf' => $row_cadastro->estado, //opcional
						'cep' => limparNumero($row_cadastro->cep), //opcional
						'inscricao_estadual' => $row_cadastro->ie, //opcional
						'inscricao_municipal' => $row_cadastro->im //opcional
					);

					$nota_simples['cliente'] = $array_cliente;
					$cadastro_valido = true;
				} else {
					echo "<br><br>---------------------------------<br>";
					echo lang('MSG_ERRO_CPF_INVALIDO')."( $row_cadastro->cpf_cnpj )";
					echo "<br>---------------------------------<br><br>";
					$cadastro_valido = false;
				}
			}

			if ($cnpj_contador) {
				$array_contador = array();
				$array_contador[] = array(
					'cpfCnpj' => $cnpj_contador
				);
				$nota_simples['autorizacaoDownloadXml'] = $array_contador;
			}

			if($debug) {
				echo "AMBIENTE: $ambiente </br>";
				echo "UUID: $uuid_venda </br>";
				echo "</br>--- INICIO REGISTRO DE VENDA ---</br>";
				print_r($row_venda);
				echo "</br>--- FINAL REGISTRO DE VENDA ---</br>";
				echo "</br>--- INICIO DA NOTA ANTES DA CONVERSAO ---</br>";
				print_r($nota_simples);
				echo "</br>--- FINAL DA NOTA ANTES DA CONVERSAO ---</br>";
				echo "</br>--- INICIO NOTA JSON ---</br>";
				$json_nota = json_encode($nota_simples);
				echo $json_nota;
				echo "</br>--- FIM NOTA JSON ---</br></br>";
			}

			if ($cadastro_valido) {
				$retorno = getEmitirNFC($cnpj_emissor, $nota_simples, $uuid_venda);

				if($debug) {
					echo "</br>--- RETORNO COMPLETO ---</br>";
					echo json_encode($retorno);
					echo "</br>--- FIM RETORNO ---</br>";
				}

				if(!$retorno['sucesso']) {
					$mensagens = [];

					foreach ($retorno['errors'] as $campo => $errosDoCampo) {
						$campoFormatado = $mapaCampos[$campo] ?? strtoupper($campo);

						// Caso o valor seja string com aspas extras e unicode, decodifica
						if (is_string($errosDoCampo)) {
							// Exemplo: "\"Mensagem com unicode\""
							$mensagem = json_decode($errosDoCampo); // remove aspas e unicode

							// fallback caso json_decode falhe
							if ($mensagem === null) {
								$mensagem = $errosDoCampo;
							}
						} elseif (is_array($errosDoCampo)) {
							// Junta erros de array normalmente
							$mensagem = implode(' | ', $errosDoCampo);
						} else {
							$mensagem = (string)$errosDoCampo;
						}
						$mensagens[] = $campoFormatado . ': ' . $mensagem;
					}

					$data = array(
						'uuid' => Uuid::uuid4(),
						'data_emissao' => "NOW()",
						'status_enotas' => 'Negada',
						'motivo_status' => implode(" | ", $mensagens),
						'fiscal' => (!$retorno['sucesso']) ? 1 : 0,
						'usuario' => session('nomeusuario'),
						'data' => "NOW()"
					);
					$db->update("vendas", $data, "id=" . $id);

					echo $motivo = implode(" | ", $mensagens);
				} else {
					$dados_emissao = $retorno['data'];
					$data_emissao = $dados_emissao['data_emissao'];
					$numero_nota = $dados_emissao['numero'] . "-". $dados_emissao['serie'];
					$status_emissao = ($dados_emissao['estado_emissao'] == "autorizado") ? "Autorizada": $dados_emissao['estado_emissao'];

					//Este procedimento de subtrair três horas da data de emissão é necessário pois a API gera um horário com três horas a mais no registro
					//das notas. Mas na danfe, a própria api gerar o horário correto e na sefaz o horário também vai correto.
					$dataRetornoAPI = new DateTime($data_emissao);
					$dataRetornoAPI->sub(new DateInterval('PT03H00S'));
					$data_emissao = $dataRetornoAPI->format('Y-m-d H:i:s');

					$data = array(
						'uuid' => Uuid::uuid4(),
						'id_emissao' => $dados_emissao['id'],
						'numero_nota' => $numero_nota,
						'numero' => $dados_emissao['numero'],
						'serie' => $dados_emissao['serie'],
						'chaveacesso' => $dados_emissao['chave_acesso'],
						'link_danfe' => $dados_emissao['link_pdf'],
						'link_download_xml' => $dados_emissao['link_xml'],
						'status_enotas' => $status_emissao,
						'motivo_status' => $retorno['message'],
						'contingencia' => ($dados_emissao['contingencia']) ? 1 : 0,
						'data_emissao' => $data_emissao,
						'fiscal' => (empty($dados_emissao['chave_acesso'])) ? 0 : 1,
						'usuario' => session('nomeusuario'),
						'data' => "NOW()"
					);
					$db->update("vendas", $data, "id=" . $id);

					$pdf = $dados_emissao['link_pdf'];
					header("Location: $pdf");
				}
			} else {
				echo "<br><br>---------------------------------<br>";
				echo lang('MSG_ERRO_CPF_INVALIDO')."( $row_cadastro->cpf_cnpj )";
				echo "<br>---------------------------------<br><br>";
			}
		}
	} catch(\Exception $ex) {
		$retorno = $ex();

		if(validaTexto($retorno, "NFe0003")) {
			$mensagens = [];

			foreach ($retorno['errors'] as $campo => $errosDoCampo) {
				$campoFormatado = $mapaCampos[$campo] ?? strtoupper($campo);

				// Caso o valor seja string com aspas extras e unicode, decodifica
				if (is_string($errosDoCampo)) {
					// Exemplo: "\"Mensagem com unicode\""
					$mensagem = json_decode($errosDoCampo); // remove aspas e unicode

					// fallback caso json_decode falhe
					if ($mensagem === null) {
						$mensagem = $errosDoCampo;
					}
				} elseif (is_array($errosDoCampo)) {
					// Junta erros de array normalmente
					$mensagem = implode(' | ', $errosDoCampo);
				} else {
					$mensagem = (string)$errosDoCampo;
				}
				$mensagens[] = $campoFormatado . ': ' . $mensagem;
			}

			$data = array(
				'uuid' => Uuid::uuid4(),
				'data_emissao' => "NOW()",
				'status_enotas' => 'Negada',
				'motivo_status' => implode(" | ", $mensagens),
				'fiscal' => 1,
				'usuario' => session('nomeusuario'),
				'data' => "NOW()"
			);
			$db->update("vendas", $data, "id=" . $id);

			$retorno = $cadastro->getConsultarNFC($cnpj_emissor,$idExterno);
			$dados_emissao = $retorno['data'];
			$links = $dados_emissao['links'];
			$pdf = $links['pdf'];
			header("Location: $pdf");
		} else {
			echo $ex();
		}
	}

	function getEmitirNFC($cnpj_emissor, $nota_simples, $uuid_venda)
	{
		$curl = curl_init();
		$url = "https://fiscal.sigesis.com.br/api/v1/nfce";

		curl_setopt_array($curl, array(
			CURLOPT_URL => $url,
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
			CURLOPT_CUSTOMREQUEST => "POST",
			CURLOPT_HTTPHEADER => array(
				"Content-Type: application/json",
				"Accept: application/json",
				"X-CNPJ:".$cnpj_emissor,
				"X-Idempotency-Key: " . $uuid_venda,
			),
			CURLOPT_POSTFIELDS => json_encode($nota_simples),//Aqui envia o array de dados
		));
		$response = curl_exec($curl);

		curl_close($curl);
		return json_decode($response, true);
	}
?>