<?php

namespace Oneweb\SimuladorSitef;

class GerarConfirmacao
{
    private Arquivo $arquivo;
    private IoInterface $io;
    private Config $config;

    public function __construct(Arquivo $arquivo, IoInterface $io = new IoMemory(), ?Config $config = null)
    {
        $this->arquivo = $arquivo;
        $this->io = $io;
        $this->config = $config ?? new Config();
    }

    public function getConfirmacao(): string
    {
        if ($this->arquivo->isConfirmacaoImpressao()) {
            $this->io->out('Enviando resposta de confirmação de impressão:');
            return $this->getConfirmacaoImpressao();
        }

        $str = "000-000 = " . $this->arquivo->getConteudoRegistro("000") . "\r\n";
        $str .= "001-000 = " . $this->arquivo->getConteudoRegistro("001") . "\r\n";
        $str .= "999-999 = 0";

        $this->io->out('Enviando resposta de confirmação de Cartão, Pix ou Coleta de dados:');

        return $str;
    }

    public function getRespostaRequisicao(): string
    {
        $conteudo = str_replace(
            [
                '#codigo#',
                '#valor#',
                '#nsu#',
                '#codigo_autorizacao#',
                '#nsu_sitef#',
            ],
            [
                $this->arquivo->getConteudoRegistro('001-000'),
                $this->arquivo->getConteudoRegistro('003-000'),
                $this->gerarCodigo(),
                $this->gerarCodigo(8),
                $this->gerarCodigo(10),

            ],
            file_get_contents($this->getArquivoModelo())
        );

        return $conteudo;
    }

    private function getArquivoModelo(): string
    {
        if ($this->arquivo->isRequisicaoColetaDados()) {
            $isCnpj = $this->arquivo->getConteudoRegistro('376-000') == '3';
            if ($isCnpj) {
                $this->io->out('Retornando arquivo coleta de CNPJ');
                return dirname(__DIR__) . '/exemplos/ExemploIntPosCNPJ.001';
            }

            $this->io->out('Retornando arquivo coleta de CPF');
            return dirname(__DIR__) . '/exemplos/ExemploIntPosCPF.001';
        }

        $valor = $this->arquivo->getConteudoRegistro('003-000');
        $possuiCentavos = false;
        if ($valor !== null) {
            $possuiCentavos = substr($valor, -2) != '00';
        }

        $negarTransacao = $possuiCentavos;
        if ($this->config->deveNegar()) {
            $negarTransacao = true;
        }

        if ($this->config->deveAutorizar()) {
            $negarTransacao = false;
        }

        $this->io->out('Requisitado pagamento no valor de ' . $valor);

        if ($this->arquivo->isRequisicaoPix()) {
            if ($negarTransacao) {
                $this->io->out('Rejeição de PIX');
                return dirname(__DIR__) . '/exemplos/ExemploIntPosPIXRejeitado.001';
            }
            $this->io->out('Aprovação de PIX');
            return dirname(__DIR__) . '/exemplos/ExemploIntPosPIXAprovado.001';
        }

        if ($this->arquivo->isRequisicaoCartao()) {
            if ($negarTransacao) {
                $this->io->out('Rejeição de Cartão');
                return dirname(__DIR__) . '/exemplos/P4-Negado-IntPos.001';
            }
            $this->io->out('Aprovação de Cartão');
            return dirname(__DIR__) . '/exemplos/P4-Aprovado-IntPos.001';
        }

        throw new \RuntimeException('Tipo de arquivo desconhecido!');
    }

    public function getConfirmacaoImpressao(): string
    {
        $str = "000-000 = CNF\r\n";
        $str .= "001-000 = " . $this->arquivo->getConteudoRegistro("001-000") . "\r\n";
        $str .= "999-999 = 0";

        return $str;
    }

    public function gerarCodigo(int $qtdCaracteres = 6): string
    {
        $str = "";
        for ($i = 0; $i < $qtdCaracteres; $i++) {
            $str .= rand(0, 9);
        }

        return $str;
    }
}
