<?php

class ProcesoFirmaElectronica
{
    
    /**
     * @var DocumentoFel
     */
    private $documento_fel;
    private Respuesta $respuestaXml;
    private RequestTransaction $requestTransaction;
    private string $felXmlFileName;

    /**
     * Get the value of documento_fel
     */
    public function getDocumentoFel()
    {
        return $this->documento_fel;
    }

    /**
     * Set the value of documento_fel
     *
     * @return  self
     */
    public function setDocumentoFel($documento_fel)
    {
        $this->documento_fel = $documento_fel;

        return $this;
    }

    /**
     * Set the value of documento_fel
     *
     * @return  self
     */
    public function setFelXmlFileName($felXmlFileName = '')
    {
        $this->felXmlFileName = $felXmlFileName ? $felXmlFileName : "factura" . "-" . uniqid();

        return $this;
    }

    public function ejecutar()
    {
        $this->setFelXmlFileName();
        if ($this->documento_fel) {
            // Generar XML
            $this->generarXml();
            // Validar XML
            if ($this->validarXml()) {
                // Generar RequestTransaction
                $this->generarRequestTransaction();
                $generarXmlG4s = new GenerarXmlG4s();
                $xmlG4s = $generarXmlG4s->requestTransactionToXmlbyString($this->requestTransaction);
                $firmarDocumentoG4s = new FirmarDocumentoG4s();
                $respuestaG4s = $firmarDocumentoG4s->ejecutar($xmlG4s);
                if ($respuestaG4s["status"]) {
                    $xmlResponse = simplexml_load_string($respuestaG4s["response"]);
                    $content2 = str_replace(array_map(function ($e) {
                        return "$e:";
                    }, array_keys($xmlResponse->getDocNamespaces())), array(), $xmlResponse->asXML());
                    $xmlParse = simplexml_load_string($content2);
                    $requestTransactionResponse = new RequestTransactionResponse();
                    $requestTransactionResponse->setRequestTransactionResultbyObject($xmlParse->Body->RequestTransactionResponse->RequestTransactionResult);
                    $objetoG4s = new ObjetoG4s();
                    $objetoG4s->setRequestTransactionResult($requestTransactionResponse->getRequestTransactionResult());
                    return $objetoG4s->ejecutar();
                }
            }
        }
        // RegistroLogs::getInstance()->error("Objeto documento fel vacio.", ['nombre' => $this->felXmlFileName]);
        return null;
    }

    private function generarXml()
    {
        if ($this->documento_fel) {
            // Object to generate XML
            $generar_xml = new GenerarXml();
            // for certification
            $this->respuestaXml = $generar_xml->ToXml($this->documento_fel);
        }
    }

    private function validarXml()
    {
        if ($this->getXml()) {
            $validarXml = new ValidarXml();
            $validarXml->setEntradaXmlFromString($this->getXml());
            $validarXml->setRutaXsd(ObtenerRutaArchivos::obtenerXsdDteFel());
            // RegistroLogs::getInstance()->error("obtenerXsdDteFel", ['nombre' => $this->getXml()]);
            return $validarXml->ejecutar();
        }
        return false;
    }

    private function getXml()
    {
        return $this->respuestaXml ? $this->respuestaXml->getXml() : '';
    }

    private function generarRequestTransaction()
    {
        $emisor = $this->documento_fel->getDatosEmisor();
        // TODO add constants
        $this->requestTransaction = new RequestTransaction();
        $this->requestTransaction->setRequestor($emisor->getRequestor());
        $this->requestTransaction->setTransaction('SYSTEM_REQUEST');
        $this->requestTransaction->setCountry($emisor->getPais());
        $this->requestTransaction->setEntity($emisor->getNitEmisor());
        $this->requestTransaction->setUser($emisor->getUser());
        $this->requestTransaction->setUsername($emisor->getUsername());
        $this->requestTransaction->setData1('POST_DOCUMENT_SAT');
        $this->requestTransaction->setData2($this->getXml());
        $this->requestTransaction->setData3(uniqid());
    }
}
