<?php
date_default_timezone_set('America/Guatemala');

use Dotenv\Dotenv;
// use JsonMapper\JsonMapper;

require __DIR__ . '/vendor/autoload.php';

$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load();

include('./clases.php');

try {
    header('Access-Control-Allow-Origin: *');
    header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method");
    header("Access-Control-Allow-Methods: POST, OPTIONS");
    header("Allow: POST, OPTIONS");
    // get the HTTP method, path and body of the request
    $method = $_SERVER['REQUEST_METHOD'];
    // $request = explode('/', trim($_SERVER['PATH_INFO'], '/'));
    $input = json_decode(file_get_contents('php://input'), true);

    $datos_emisor = new DatosEmisor();
    $documento_fel = new DocumentoFel();

    // setting "emisor" data
    $datos_emisor->setAfiliacionIVA($input['emisor']['afiliacion']);
    $datos_emisor->setCodigoEstablecimiento($input['emisor']['cod_establecimiento']);
    $datos_emisor->setCodigoPostal($input['emisor']['cod_postal']);
    $datos_emisor->setCorreoEmisor($input['emisor']['correo']);
    $datos_emisor->setDepartamento($input['emisor']['departamento']);
    $datos_emisor->setMunicipio($input['emisor']['municipio']);
    $datos_emisor->setDireccion($input['emisor']['direccion']);
    $datos_emisor->setNITEmisor($input['emisor']['nit']);
    $datos_emisor->setNombreComercial($input['emisor']['nombre_com']);
    $datos_emisor->setNombreEmisor($input['emisor']['nombre_em']);
    $datos_emisor->setPais($input['emisor']['pais']);
    $datos_emisor->setRequestor($input['emisor']['requestor']);
    $datos_emisor->setUser($input['emisor']['user']);
    $datos_emisor->setUsername($input['emisor']['username']);

    // Setting datos_emisor into documento_fel
    $documento_fel->setDatosEmisor($datos_emisor);

    // datos generales
    $datos_generales = new DatosGenerales();

    $datos_generales->setCodigoMoneda($input['general']['moneda']);
    $date = date('Y-m-d\TH:i:s');
    $dateEmision = date('Y-m-d');
    $datos_generales->setFechaHoraEmision(isset($input['general']['fecha_hora_emision']) ? $input['general']['fecha_hora_emision'] : $date);
    $datos_generales->setFechaEmision(isset($input['general']['fecha_hora_emision']) ? explode("T", $input['general']['fecha_hora_emision'])[0] : $dateEmision);
    $datos_generales->setTipo($input['general']['tipo']);

    // setting datos generales into documento_fel
    $documento_fel->setDatosGenerales($datos_generales);

    // Validar NIT
    $validarNIT = new ValidarNIT();
    $respuestaValidacionNIT = $validarNIT->ejecutar($input['receptor']['id_receptor']);
    // RegistroLogs::getInstance()->info("respuestaValidacionNIT", ['respuestaValidacionNIT' => ($respuestaValidacionNIT)]);
    // RegistroLogs::getInstance()->info("respuestaValidacionNIT", ['respuestaValidacionNIT' => (isset($respuestaValidacionNIT['nombreCompletoRegistrado']) ? $respuestaValidacionNIT['nombreCompletoRegistrado'] : $input['receptor']['nombre'])]);

    // datos receptos
    $datos_receptor = new DatosReceptor();
    $datos_receptor->setCodigoPostal($input['receptor']['cod_postal']);
    $datos_receptor->setCorreoReceptor($input['receptor']['correo']);
    $datos_receptor->setDepartamento($input['receptor']['departamento']);
    $datos_receptor->setDireccion($input['receptor']['direccion']);
    $datos_receptor->setIDReceptor($input['receptor']['id_receptor']);
    $datos_receptor->setMunicipio($input['receptor']['municipio']);
    $datos_receptor->setNombreReceptor(isset($respuestaValidacionNIT['nombre']['nombreCompletoRegistrado']) ? $respuestaValidacionNIT['nombre']['nombreCompletoRegistrado'] : $input['receptor']['nombre']);
    $datos_receptor->setPais($input['receptor']['pais']);

    // setting datos receptos into documento_fel 
    $documento_fel->setDatosReceptor($datos_receptor);

    $items = $input['items'];
    $impuesto_total = 0;
    $grand_total = 0;
    $grand_descuento = 0;

    foreach ($items as $key => $item) {

        // Items containers
        $items = new Items();

        $items->setNumeroLinea($key + 1);
        $items->setBienOServicio($item['BoS']);
        $items->setCantidad($item['cantidad']);
        $items->setDescripcion($item["descripcion"]);
        $items->setDescuento($item['descuento']);
        $items->setDescuentoPorcentual($item['descuentoPorcentual']);
        $items->setPrecio($item['precio']); //  $item['precio_unitario'] * $item['cantidad']
        $items->setPrecioUnitario($item['precio_unitario']);
        $items->setUnidadMedida($item['unidad_medida']);
        $total = $item['precio'] - $item['descuento'];
        $descuento = $item['descuento'];
        $items->setTotal($total); // $item['precio'] - $item['descuento']
        $grand_total += $total;
        $grand_descuento += $descuento;

        // Setting impuestos
        // if there where multiple taxes (impuestos): we must build a loop that iterates across the multiple taxes (impuestos)

        // new ImpuestoDetalle
        $impuestos_detalle = new ImpuestosDetalle();

        $monto_grabable = $total / 1.12;
        $impuestos_detalle->setNombreCorto("IVA");
        $impuestos_detalle->setCodigoUnidadGravable(1);
        $impuestos_detalle->setMontoGravable($monto_grabable);
        //$impuestos_detalle->setCantidadUnidadesGravables(78.00);
        // we must build a matriz/associative array to get taxes by name.
        //  "IVA" -  for now only "IVA" is necessary
        $monto_impuesto = $monto_grabable * 0.12;
        $impuestos_detalle->setMontoImpuesto($monto_impuesto);
        $impuesto_total += $monto_impuesto;

        $items->setImpuestosDetalle($impuestos_detalle);

        // saving item
        $documento_fel->setItems($items);
    }

    // setting total impuestos 
    $total_impuestos = new TotalImpuestos();

    $total_impuestos->setNombreCorto("IVA");
    $total_impuestos->setTotalMontoImpuesto($impuesto_total);
    $documento_fel->setImpuestosResumen($total_impuestos);


    // setting grand total
    $totales = new Totales();
    $totales->setGranTotal($grand_total);
    $documento_fel->setTotales($totales);
    $documento_fel->setDescuentos($grand_descuento);

    // setting frases
    $frase1 = new Frases();
    $frase1->setTipoFrase(1);
    $frase1->setCodigoEscenario(1);
    $documento_fel->setfrases($frase1);

    // Complementos
    if (isset($input['complementos'])) {
        $complementos = new ComplementoCambiaria();
        $complementos->setIdComplemento('AbonosFacturaCambiaria');
        $complementos->setNombreComplemento('AbonosFacturaCambiaria');
        $complementos->setUriComplemento("http://www.sat.gob.gt/dte/fel/CompCambiaria/0.1.0");
        $abonosFacturaCambiaria = $input['complementos']['abonosFacturaCambiaria'];
        foreach ($abonosFacturaCambiaria as $key => $item) {
            $abonoFacturaCambiaria = new AbonosFacturaCambiaria();

            $abonoFacturaCambiaria->setFechaVencimiento($item['fechaVencimiento']);

            $abonoFacturaCambiaria->setNumeroAbono($item['numeroAbono']);

            $abonoFacturaCambiaria->setMontoAbono($item['montoAbono']);

            $complementos->setAbono($abonoFacturaCambiaria);
        }


        $documento_fel->setComplementos($complementos);
    }

    // we have classes to add addendums (Adendas/notas-extras)... if needed they must be used below

    // Object to generate XML
    $generar_xml = new GenerarXml();
    // for certification
    $respuesta = $generar_xml->ToXml($documento_fel);

    $xmlFileName = "factura-" . uniqid() . ".xml";

    // Xml validation
    // $validarXml = new ValidarXml();
    // $validarXml->setEntradaXmlFromString($respuesta->getXml());
    // $validarXml->setRutaXsd(ObtenerRutaArchivos::obtenerXsdDteFel());
    // $xmlStatusResult = $validarXml->ejecutar();

    // RegistroLogs::getInstance()->info("Estado del xml.", ['nombre' => $xmlFileName, 'esValido' => $xmlStatusResult]);
    $procesoFirmaElectronica = new ProcesoFirmaElectronica();
    $procesoFirmaElectronica->setDocumentoFel($documento_fel);

    // Generate file
    $myfile = fopen($xmlFileName, "w") or die("Unable to open file!");
    fwrite($myfile, $respuesta->getXml());
    fclose($myfile);
    // echo "Docto XML";
    // echo '<hr>';

    header('Content-Type: application/json');
    echo $procesoFirmaElectronica->ejecutar();
} catch (Exception $e) {
    echo 'Excepción capturada: ',  $e->getMessage(), "\n";
}
