<?php


// Aumentar el tiempo de ejecución si es necesario
set_time_limit(10); // Aumentar a 10 segundos, ajusta según sea necesario

// Función para enviar la factura (solo un intento)
function enviar_factura($url, $data, $token) {
    try {
        $options = [
            'http' => [
                'header' => "Content-type: application/json\r\nAuthorization: $token",
                'method' => 'POST',
                'content' => json_encode($data)
            ]
        ];
        $context = stream_context_create($options);
        // REMUEVE @ para permitir que los errores se propaguen
        $response = file_get_contents($url, false, $context);

        if ($response === false) {
            // Lanza una excepción que será capturada por el script principal
            throw new Exception("Error al enviar la factura. La API no está disponible o respondió con error.");
        }

        $result = json_decode($response, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new Exception("Error al decodificar la respuesta de la factura: " . json_last_error_msg());
        }

        // Si la respuesta es exitosa
        if (isset($result["success"]) && $result["success"] == true) {
            return $result; // Retorna la respuesta exitosa
        } else {
            // Asegúrate de extraer el mensaje de error correctamente, o proporciona uno genérico
            $errorMessage = "Error desconocido al procesar la factura.";
            if (isset($result["errores"]["errores"][0]["errorMessage"])) {
                $errorMessage = $result["errores"]["errores"][0]["errorMessage"];
            } elseif (isset($result["message"])) {
                $errorMessage = $result["message"];
            }
            throw new Exception("Error al procesar la factura: " . $errorMessage);
        }
    } catch (Exception $e) {
        // Registra el error internamente si es necesario, pero relánzalo para asegurar la propagación
        file_put_contents('mensajeError.txt', date('Y-m-d H:i:s') . " - " . $e->getMessage() . "\n", FILE_APPEND);
        throw $e; // Relanza la excepción
    }
}

try {
    if (isset($TipoFactura)) {
        $connn = new conexion();
        $conectar = $connn->conectar();

        $factur = $GLOBALS["facturaBodega"];

        $factura = "SELECT `tipoId`, `cedula`, `Nombre`, `direccion`,
        `telefono`, `apellido`, `correo`, `dv`, `naturaleza`, `regimen`,
         `responsabilidad`, `codigociudad`, `numeroResolucionElectro`,
          `prefijoElectro`, `userApi`, `passApi`, facturas.factura,
           `valor`, `fechaFactura`, `F.Pago_Electro`,
            `Fecha_Venci_Electro`, `M.Pago_Electro`,
             nit, detallef, bodegaEm,`sucursalFacClient`,
         `direcionSc`,`TelSuc`,`otrDato1`,`otrDato2`
        FROM `facturas`
        INNER JOIN empresa ON facturas.idbodegaF = empresa.bodegaEm
        INNER JOIN clientes ON facturas.cliente = clientes.cedula
        LEFT JOIN sucursalesclientes on facturas.sucursalFacClient=sucursalesclientes.id
        WHERE tipoFactura='Electronica' AND EstadoEjecucion='0' AND cufe='0' AND facturas.devolucion='0' AND ActivarFacturacionElectronica=1 AND Pos_Electronico='0' AND facturas.factura=?
        LIMIT 1";

        $stmt = $conectar->prepare($factura);
        $stmt->bind_param("s", $factur);
        $stmt->execute();
        $resultado = $stmt->get_result();
    } else {
           $factura = "SELECT `tipoId`, `cedula`, `Nombre`, `direccion`,
         `telefono`, `apellido`, `correo`, `dv`, `naturaleza`, 
         `regimen`, `responsabilidad`, `codigociudad`,
          `numeroResolucionElectro`, `prefijoElectro`,
           `userApi`, `passApi`, facturas.factura,
            `valor`, `fechaFactura`, `F.Pago_Electro`,
             `Fecha_Venci_Electro`, `M.Pago_Electro`,
              nit, detallef, bodegaEm,`sucursalFacClient`,
         `direcionSc`,`TelSuc`,`otrDato1`,`otrDato2`
        FROM `facturas`
        INNER JOIN empresa ON facturas.idbodegaF = empresa.bodegaEm
        INNER JOIN clientes ON facturas.cliente = clientes.cedula 
        LEFT JOIN sucursalesclientes on facturas.sucursalFacClient=sucursalesclientes.id
        WHERE tipoFactura='Electronica' AND EstadoEjecucion='0' AND cufe='0' AND facturas.devolucion='0' AND ActivarFacturacionElectronica=1 AND Pos_Electronico='0'
        LIMIT 1";
        
        $stmt = $conectar->prepare($factura);
        $stmt->execute();
        $resultado = $stmt->get_result();
    }

    if ($resultado->num_rows > 0) {
        $fila = $resultado->fetch_assoc();
        $factur = $fila["factura"];
        $bodega = $fila["bodegaEm"];

        $conectar->query("UPDATE `facturas` SET `EstadoEjecucion`='1' WHERE factura='$factur'");

        $productosQuery = "SELECT * FROM `ventas` INNER JOIN productos ON ventas.codigoProducto = productos.codigo WHERE factura=?";
        $stmt1 = $conectar->prepare($productosQuery);
        $stmt1->bind_param("s", $factur);
        $stmt1->execute();
        $resultado1 = $stmt1->get_result();
        $fila1 = $resultado1->fetch_all(MYSQLI_ASSOC);

        $productos = [];
        foreach ($fila1 as $value) {
            $tipoProduct = $value["tipoProduct"];
            $precioVenta = $value["valor"];

            if (($tipoProduct == "hibrido" || $tipoProduct == "Fabricacion") && $precioVenta == 0) {
                continue;
            }

            // $caja = $value["cantCaja"];
            // $frcc = $value["cantfrcc"];

            // $cnatidad = (int)$caja + (int)$frcc;
            $caja = (float)$value["cantCaja"];   // aceptar decimales como 0.5
            $frcc = (float)$value["cantfrcc"];   // aceptar fracciones también

            $cnatidad = $caja + $frcc;  

            $tipoiva = $value["tipoiva"];
            $valorNombre = $value["nombre"];
            $idVencimeinto= $value["idVencimeinto"];
            if($idVencimeinto==0 || $idVencimeinto=="0"){
                $idVencimeinto="";
            }

            if ($cnatidad != 0) {
                 $costounitario = $value["valor"] / $cnatidad;
            } else {
                $costounitario = $value["valor"];
            }

            $valorCodigo = $value["codigoProducto"];

            switch ($tipoiva) {
                case "19":
                    $iva = "IVA_19";
                    break;
                case "5":
                    $iva = "IVA_5";
                    break;
                case "0":
                    $iva = "EXCENTO";
                    break;
                case "1":
                    $iva = "EXCLUIDO";
                    break;
                case "8":
                    $iva = "IMPUESTO_CONSUMO_8";
                    break;
                default:
                    $iva = "OTRO_VALOR_POR_DEFECTO";
            }

            $productos[] = [
                "nombreItemVenta" => $valorNombre ." ".$idVencimeinto,
                "precioVentaUnitario" => $costounitario,
                "precioReferencia" => 0,
                "cantidad" => $cnatidad,
                "codigo" => $valorCodigo,
                "descuentoPorcentaje" => 0,
                "observacion" => "",
                "unidad" => "94",
                "codigoDescuento" => "04",
                "impuesto" => $iva
            ];
        }

         //nombre cliente
        if (!isset($fila["otrDato1"]) || !is_string($fila["otrDato1"]) || empty(trim($fila["otrDato1"]))) {
            $nombreC=$fila["Nombre"] . " " . $fila["apellido"];
        }else{

            $nombreC=$fila["otrDato1"];
        }

        //diereccion
        if (!isset($fila["direcionSc"]) || !is_string($fila["direcionSc"]) || empty(trim($fila["direcionSc"]))) {
            $direccion=$fila["direccion"];
        }else{

            $direccion=$fila["direcionSc"];
        }

         //telefono
         if (!isset($fila["TelSuc"]) || !is_string($fila["TelSuc"]) || empty(trim($fila["TelSuc"]))) {
            $telefono=$fila["telefono"];
        }else{

            $telefono=$fila["TelSuc"];
        }
        $mediosPago=$fila["M.Pago_Electro"];
        if($fila["F.Pago_Electro"]==2){
            $mediosPago=1;
        }

        $tipoIdentifica=$fila["tipoId"];
        if($fila["tipoId"]=="Otro"){
                $tipoIdentifica="CC";
        }

        $fechaF = date('Y-m-d') . 'T' . date('H:i');
        $facturaelectronica = [
            "nit" => $fila["nit"],
            "numeroResolucion" => $fila["numeroResolucionElectro"],
            "numeroDocumentoComercial" => $fila["factura"],
            "fechaGeneracion" => $fechaF,
            "fechaVencimiento" => $fila["Fecha_Venci_Electro"],
            "mediosPago" => $mediosPago,
            "observacion" => $fila["detallef"],
            "formaPago" => $fila["F.Pago_Electro"],
            "total" => $fila["valor"],
            "cliente" => [
                "nombreRazonSocial" =>$nombreC,
                "tipoIdentificacion" =>  $tipoIdentifica,
                "numIdentificacion" => $fila["cedula"],
                "naturaleza" => $fila["naturaleza"],
                "direccion" => $direccion,
                "ciudad" => $fila["codigociudad"],
                "telefono" =>$telefono,
                "email" => $fila["correo"],
                "responsabilidadesFiscales" => $fila["responsabilidad"],
                "respTributarias" => $fila["regimen"]
            ],
            "codigoDescuento" => "04",
            "porcentajeDescuentoGeneral" => 0,
            "items" => $productos
        ];

        // Manejo de token y envío de la factura con un solo intento
        if (isset($_SESSION[$bodega]["toke"])) {
            $token = $_SESSION[$bodega]["toke"];
        } else {
            $userrApi = $fila["userApi"];
            $passApi = $fila["passApi"];

            // URL para obtener el token
            $url = "https://csi.clarisa.co:8443/seguridad/rest/api/v1/login/";
            $data = ['usuario' => $userrApi, 'contrasenia' => $passApi];
            $options = [
                'http' => [
                    'header' => "Content-type: application/json",
                    'method' => 'POST',
                    'content' => json_encode($data)
                ]
            ];
            $context = stream_context_create($options);

            try {
                // REMUEVE @ para permitir que los errores se propaguen
                $response = file_get_contents($url, false, $context);
                if ($response === false) {
                    throw new Exception("Error al obtener el token. No se pudo conectar con la API.");
                }

                $result = json_decode($response, true);
                if (json_last_error() !== JSON_ERROR_NONE) {
                    throw new Exception("Error al decodificar la respuesta JSON: " . json_last_error_msg());
                }

                $token = $result["data"]["token"] ?? null;
                if (!$token) {
                    // Verifica si hay un mensaje de error específico de la API
                    $errorMessage = "El token no se encontró en la respuesta.";
                    if (isset($result["message"])) {
                        $errorMessage .= " Mensaje de la API: " . $result["message"];
                    }
                    throw new Exception($errorMessage);
                }

                $_SESSION[$bodega] = ["toke" => $token];
            } catch (Exception $e) {
                file_put_contents('mensajeError.txt', "Error al obtener el token: " . $e->getMessage() . "\n", FILE_APPEND);
                throw $e; // Relanza la excepción para que sea capturada por el script principal
            }
        }

        // Si se obtuvo el token, se procede con el envío de la factura
        if ($token !== null) {
            $url = "https://csi.clarisa.co:8443/facturas/rest/api/v1/factura";
            $resulta = enviar_factura($url, $facturaelectronica, $token);

            if ($resulta !== null) {
                // Verifica si CUFE está definido antes de asignarlo
                if (isset($resulta["data"]["cufe"])) {
                    $cufe = $resulta["data"]["cufe"];
                    $conectar->query("UPDATE `facturas` SET `EstadoEjecucion`='1', `cufe`='$cufe', `mensajeProveTecno`='Factura Creada Con exito' WHERE factura='$factur'");
                } else {
                    $conectar->query("UPDATE `facturas` SET `mensajeProveTecno`='La respuesta de la API no contiene CUFE.' WHERE factura='$factur'");
                    // Es una buena práctica lanzar una excepción aquí también si el CUFE es crítico
                    throw new Exception("La API de facturación no devolvió un CUFE válido.");
                }

            } else {
                $conectar->query("UPDATE `facturas` SET `mensajeProveTecno`='No se pudo enviar la factura.' WHERE factura='$factur'");
                // Lanza una excepción aquí para asegurar que el catch principal se active
                throw new Exception("No se pudo enviar la factura electrónica.");
            }
        } else {
            // Si el token es nulo, una excepción ya debería haber sido lanzada.
            // Este bloque else actúa como una salvaguarda.
            throw new Exception("No se pudo obtener el token para la facturación electrónica.");
        }
    }
} catch (Exception $e) {
    // Este bloque catch en el archivo incluido solo debe registrar y luego relanzar
    // para asegurar que el bloque catch del script principal también lo reciba.
    file_put_contents('mensajeError.txt', "Error en facturacionElectronica.php: " . $e->getMessage() . "\n", FILE_APPEND);
    throw $e; // Relanza la excepción
}
?>
