<?php

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: *');

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

ignore_user_abort(true); // Ignorar la desconexión del usuario
set_time_limit(0); // Tiempo de ejecución infinito

require '../../modelo/orden.php';
require '../../modelo/usuario.php';
require '../usuario/decodeUsuario.php';
require '../../modelo/direccion_envio.php';
require '../../modelo/carrito.php';
require '../../modelo/producto_variacion.php';
require '../../modelo/tipo_variacion.php';
require '../../modelo/producto_orden.php';
require '../../modelo/guia_producto_orden.php';
// require '../../modelo/environment.php';
require '../../modelo/direccion_facturacion.php';
require '../envio/costo_envio.php';
require '../envio/costo_paqueteria.php';
require_once '../../modelo/almacenes_odoo.php';
require_once '../../modelo/odoo_inventario.php';
require_once '../../modelo/odoo_orden_venta.php';
require_once '../../modelo/odoo_cliente.php';
require '../../modelo/guia_envio_producto.php';
require '../../modelo/guia_envio_zona_extendida_producto.php';
require '../../modelo/guia_envio_orden.php';
require '../../modelo/openpay.php';
require '../../modelo/pago.php';
require '../../modelo/paqueteria.php';
require '../pak2go/generarGuia.php';
require '../../modelo/precio.php';
require '../../modelo/correo.php';

$response = array();
$url_servidor = Environment::getUrlServidor();

function generarIdentificador($numero_caracteres = 10)
{
    $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $numero_orden = 'MTM';
    for ($i = 0; $i < $numero_caracteres; $i++) {
        $random_character = $characters[rand(0, strlen($characters) - 1)];
        $numero_orden .= $random_character;
    }
    return $numero_orden;
}

if (
    !isset($_POST['id_usuario']) ||
    !isset($_POST['id_direccion_envio']) ||
    // Por defecto sería la opción 1 hasta que se procese el pago
    // !isset($_POST['id_estado_orden']) ||
    !isset($_POST['id_paqueteria']) ||
    !isset($_POST['paqueteria']) ||
    !isset($_POST['id_transaccion']) ||
    !isset($_POST['pasarela_pago'])
) {
    $response['response'] = 'error';
    $response['data'] = 'Datos incompletos';
    echo json_encode($response);
    return;
}

$id_usuario = DecodeUser::handlePostUsuario($_POST['id_usuario']);

if (!$id_usuario) {
    $response['response'] = 'error';
    $response['data'] = 'Id del usuario incorrecto.';
    echo json_encode($response);
    return;
}

$info_usuario = Usuario::mdlGetUsuarioRegistro($id_usuario);

$correo_usuario = $info_usuario['correo'];

$nombre_usuario = $info_usuario['nombre'] . ' ' . $info_usuario['apellido_paterno'];

$id_transaccion = $_POST['id_transaccion'];

if (!$id_transaccion) {
    $response['response'] = 'error';
    $response['data'] = 'Id de la transación incorrecto.';
    echo json_encode($response);
    return;
}

$pasarela_pago = $_POST['pasarela_pago'];

if (!$pasarela_pago) {
    $response['response'] = 'error';
    $response['data'] = 'Pasarela de pago incorrecta.';
    echo json_encode($response);
    return;
}

$carrito = Carrito::mdlGetCarritoByIdUsuario($id_usuario);

if (!$carrito) {
    $response['response'] = 'error';
    $response['data'] = 'No se encontraron carritos';
    echo json_encode($response);
    return;
}

// echo json_encode($carrito);
// return;

$id_direccion_envio = $_POST['id_direccion_envio'];
$id_direccion_facturacion = $_POST['id_direccion_facturacion'] ?? null;
$id_paqueteria = $_POST['id_paqueteria'];
$paqueteria = $_POST['paqueteria'];

$cp = DireccionEnvio::mdlGetDireccionById($id_usuario, $id_direccion_envio)['cp'];

$data_almacenes = Envio::getOrdenOdoo($cp, $carrito, $paqueteria);

if (!$data_almacenes) {
    $response['response'] = 'error';
    $response['data'] = 'No se pudo verificar el pedido en odoo.';
    echo json_encode($response);
    return;
};

$id_lot_stock_almacen_virtual = 192;
$id_almacen_virtual = 12;
$id_usuario_odoo = Usuario::mdlGetUsuarioIdOdoo($id_usuario);
$cupon = $_POST['cupon'] ?? null;

// 1. Verificamos si el usuario solicito factura en este pedido
// Si no la solicitó, tenemos que asignarle la venta a un RFC genérico de Odoo, que lo tiene un cliente llamado 'Versa Prink'
if (is_null($id_direccion_facturacion)) {
    $id_cliente_generico = "245589"; // ID del cliente genérico de Odoo hardcodeado
    // $id_cliente_generico = OdooCliente::getClientIdByRFCOrEmail('XAXX010101000', null);
    // $id_cliente_generico = OdooCliente::getClientIdByRFCOrEmail(null, "hugogarate76@gmail.com");
    $id_cliente = $id_cliente_generico;

    $direccion_facturacion = NULL;
} else {
    // Si solicitó factura, obtenemos el ID del cliente que solicitó la factura
    $direccion_facturacion = DireccionFacturacion::mdlGetDireccionFacturacionById($id_usuario, $id_direccion_facturacion);
    $id_cliente = $id_usuario_odoo;
}

// 2. Verificar si el pedido sale de un almacén.
$almacenes = $data_almacenes['control_envio'];
$total_almacenes = count($almacenes);

$id_almacen_salida = $id_lot_stock_almacen_virtual;
$id_almacen = $id_almacen_virtual;
// Mover todos los productos al almacen virtual
foreach ($almacenes as $almacen) {
    $id_lot_stock = intval($almacen['id_lot_stock']);
    $id_tipo_picking = intval($almacen['id_tipo_picking']);
    $productos = $almacen['productos'];
    foreach ($productos as $producto) {
        $id_producto = intval($producto['id_producto_odoo']);
        $cantidad = intval($producto['cantidad']);
        $id = OdooInventario::moveProductBetweenWarehouses($id_producto, $id_lot_stock, $id_lot_stock_almacen_virtual, $id_tipo_picking, $cantidad);
    }
}

// 3. Crear la orden de venta en Odoo
$id_cuenta_analitica = 11; // <-- Ventas en linea
$id_orden_odoo = OdooOrdenVenta::addNewSaleOrder(intval($id_cliente), intval($id_almacen), intval($id_cuenta_analitica));
// print_r($id_orden_odoo);
// echo "\n";

if (!$id_orden_odoo) {
    $response['response'] = 'error';
    $response['data'] = 'No se pudo verificar el pedido en odoo.';
    echo json_encode($response);
    return;
}

$paqueteria_seleccionada = Paqueteria::mdlGetPaqueteriaById($id_paqueteria);

$nombre_paquetria_seleccionada = $paqueteria_seleccionada['nombre'];

$id_odoo_paqueteria = $paqueteria_seleccionada['id_odoo'];

$direccion_envio_usuario = DireccionEnvio::mdlGetDireccionById($id_usuario, $id_direccion_envio);

if (!$direccion_envio_usuario) {
    $response['response'] = 'error';
    $response['data'] = 'No se pudo verificar la dirección de envío del usuario.';
    echo json_encode($response);
    return;
}

// 4. Agregar los productos a la orden de venta

$detalles_pedido = array();

foreach ($almacenes as $key_almacen => $almacen) {
    $detalles_pedido[$key_almacen]['id_paqueteria'] = $id_paqueteria;
    $detalles_pedido[$key_almacen]['paqueteria'] = $paqueteria;
    $detalles_pedido[$key_almacen]['almacen'] = $almacen['almacen'];

    $productos = $almacen['productos'];

    switch ($nombre_paquetria_seleccionada) {
        case 'ENTREGA SUCURSAL':
            $id_sale_orden_envio = OdooOrdenVenta::addNewLineToSaleOrder($id_orden_odoo, intval($id_odoo_paqueteria), 1);

            $id_precio_envio = 118;

            $detalles_pedido[$key_almacen]['tracking_number'] = null;
            break;
        case 'MTM':
            $id_sale_orden_envio = OdooOrdenVenta::addNewLineToSaleOrder($id_orden_odoo, intval($id_odoo_paqueteria), 1);

            $id_precio_envio = 40;

            $detalles_pedido[$key_almacen]['tracking_number'] = null;
            break;
        default:
            $generar_guia = GenerarGuiaPak2Go::cotizarGuia($almacen, $nombre_paquetria_seleccionada, $direccion_envio_usuario, $direccion_facturacion, $correo_usuario);

            $id_sale_orden_envio = OdooOrdenVenta::addNewLineToSaleOrder($id_orden_odoo, intval($id_odoo_paqueteria), 1);

            $precio_envio_sin_iva = floatval($generar_guia['total_pricing']) / 1.16;

            $actualizar_costo_envio = OdooOrdenVenta::updatePriceOfSaleOrderLine($id_sale_orden_envio, $precio_envio_sin_iva);
            //Agregar precio de envío
            $id_precio_envio = Precio::mdlAddPrecio($generar_guia['total_pricing'], $precio_envio_sin_iva, null, null);

            $detalles_pedido[$key_almacen]['tracking_number'] = $generar_guia['tracking_number'];
            $detalles_pedido[$key_almacen]['tracking_url_provider'] = $generar_guia['tracking_url_provider'];
            break;
    }

    $detalles_pedido[$key_almacen]['id_precio'] = $id_precio_envio;

    foreach ($productos as $key_producto => $producto) {
        $id_producto_odoo = intval($producto['id_producto_odoo']);
        $id_producto = intval($producto['id_producto']);
        $cantidad = intval($producto['cantidad']);
        $id_precio = intval($producto['id_precio']);

        $id = OdooOrdenVenta::addNewLineToSaleOrder($id_orden_odoo, $id_producto_odoo, $cantidad);

        $detalles_pedido[$key_almacen]['productos'][$key_producto]['id_producto'] = $id_producto;
        $detalles_pedido[$key_almacen]['productos'][$key_producto]['id_precio'] = $id_precio;
        $detalles_pedido[$key_almacen]['productos'][$key_producto]['cantidad'] = $cantidad;
    }
}

// 7. Confirmar la orden de venta en Odoo
$sale_order_confirm = OdooOrdenVenta::confirmSaleOrder($id_orden_odoo);
// print_r($sale_order_confirm);
// echo "\n";

if (!$sale_order_confirm) {
    $response['response'] = 'error';
    $response['data'] = 'No se pudo confirmar la orden de venta.';
    echo json_encode($response);
    return;
}

// 7.1 Validamos la orden de venta
$validar_orden = OdooOrdenVenta::validateSaleOrder($id_orden_odoo);
// print_r($validar_orden);
// echo "\n";

// 8. Agregamos el mensaje personalizado a la orden de picking
$message_id = OdooOrdenVenta::addNoteToOrder(
    $id_orden_odoo,
    'Domicilio de envío: ' .
        $direccion_envio_usuario['calle'] . ' ' .
        $direccion_envio_usuario['numero_exterior'] . ' ' .
        $direccion_envio_usuario['numero_interior'] . ' ' .
        $direccion_envio_usuario['colonia'] . ' ' .
        $direccion_envio_usuario['delegacion'] . ' ' .
        $direccion_envio_usuario['estado'] . ' ' .
        $direccion_envio_usuario['cp'] . ' ' .
        'Referencia: ' .
        $direccion_envio_usuario['referencia'] . ' ' .
        'Receptor: ' .
        $direccion_envio_usuario['nombre_receptor']
);

// 8.1 Confirmamos el picking de la orden (remisionar)
$confirm_picking = OdooOrdenVenta::confirmPicking($id_orden_odoo);

// 9. Facturar automáticamente la orden de la venta
try {
    $id_factura = OdooOrdenVenta::createInvoiceFromAdvancePayment($id_orden_odoo);
} catch (Exception $e) {
    // Manejar la excepción
    error_log('Error al facturar la orden de venta: ' . $e->getMessage());
}

// 10. Obtener el id de la factura de la orden de venta
try {
    $fg_periodicity = null;
    $fg_months = null;
    $fg_year = null;
    if (is_null($id_direccion_facturacion)) {
        $fg_periodicity = "01"; // Periodicidad de la factura, que significa 'diario'
        // Obtenemos el mes actual con el formato de dos digitos
        $fg_months = date("m");
        // Obtenemos el año actual con el formato de cuatro digitos
        $fg_year = date("Y");
    }

    $confirmar_factura = OdooOrdenVenta::getInvoiceIDsAndConfirmBySaleOrderID($id_factura, $fg_periodicity, $fg_months, $fg_year);
} catch (Exception $e) {
    // Manejar la excepción
    error_log('Error al obtener el id de la factura de la orden de venta: ' . $e->getMessage());
}

//Aquí comienza suponiendo que ya se agregó a odoo el pedido y se obtuvo el id de odoo

$numero_orden = generarIdentificador();

if (Orden::mdlVerifyNumeroOrden($numero_orden)) {
    $numero_orden = generarIdentificador();
}

$orden = Orden::mdlAddOrden($numero_orden, $id_usuario, $id_direccion_envio, $id_direccion_facturacion, $id_orden_odoo);
// $orden = Orden::mdlAddOrden($numero_orden, $id_usuario, $id_direccion_envio, $id_direccion_facturacion, "TEST");

if (!$orden) {
    $response['response'] = 'error';
    $response['data'] = 'No se agregó la orden';
    echo json_encode($response);
    return;
}

$productos_correo = array();
$aux = 0;

// 11. Crear la guía de envío
foreach ($detalles_pedido as $key_detalles_pedido => $detalle_pedido) {
    $id_paqueteria = $detalle_pedido['id_paqueteria'];
    $nombre = $detalle_pedido['paqueteria'];
    $id_precio = $detalle_pedido['id_precio'];
    $id_almacen_odoo = $detalle_pedido['almacen'];

    $id_guia_envio_producto = GuiaEnvioProducto::mdlAddGuiaEnvioProducto($id_paqueteria, $nombre, $id_precio);

    $numero_rastreo = null;

    if (!is_null($detalle_pedido['tracking_number'])) {
        $numero_rastreo = $detalle_pedido['tracking_number'];
    }

    $id_guia_envio_orden = GuiaEnvioOrden::mdlAddGuiaEnvioOrden($id_guia_envio_producto, $orden, $numero_rastreo);

    $productos = $detalle_pedido['productos'];

    foreach ($productos as $key_productos => $producto) {
        $productos_correo[$aux] = $producto;
        
        $id_producto = $producto['id_producto'];
        $id_precio = $producto['id_precio'];
        $cantidad = $producto['cantidad'];

        $producto_orden = ProductoOrden::mdlAddProductoOrden($id_producto, $orden, $id_precio, null, $cantidad, $id_almacen_odoo);

        $guia_producto_orden = GuiaProductoOrden::mdlAddGuiaProductoOrden($id_guia_envio_orden, $producto_orden);
    }

    $aux++;
}

$openpay = OpenpayAuth::getOpenpayConexion();

if (!$openpay) {
    $response['response'] = 'error';
    $response['data'] = 'Error al conectar con Openpay.';
    echo json_encode($response);
    return;
}

$charge = $openpay->charges->get($id_transaccion);

// Payment method
$metodo_pago = $charge->card->type;

// Currency
$moneda = $charge->currency;

// Payment amount
$cantidad_pago = $charge->amount;

// Buyer's name
$nombre_comprador = $charge->card->holder_name;

// Payment status
$estado_pago = $charge->status;

$ip = $_SERVER['REMOTE_ADDR'];
// $ip = "192.168.1.1";

$details = json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip={$ip}"));
$pais = $details->geoplugin_countryCode;
// $pais = "MX";

$user_agent = $_SERVER['HTTP_USER_AGENT'];
// $user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36";

$pago = Pago::mdlAddPago($orden, $id_transaccion, $pasarela_pago, $metodo_pago, $moneda, $cantidad_pago, $nombre_comprador, $estado_pago, $user_agent, $ip);

if (!$pago) {
    $response['response'] = 'error';
    $response['data'] = 'No se pudo registrar el pago.';
    echo json_encode($response);
    return;
}

$correo = Correo::mdlOrdenCompletada($correo_usuario, $nombre_usuario, $productos_correo, $numero_orden, $cantidad_pago);

$response['response'] = 'success';
$response['data'] = $numero_orden;

echo json_encode($response);
