<?php

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

require_once '../../modelo/direcciones_sepomex.php';
require_once '../../modelo/odoo_inventario.php';
require_once '../../modelo/ubicacion_almacen.php';
require_once '../../modelo/odoo_producto.php';
require_once '../../modelo/cercania_almacen_odoo.php';
require_once '../../modelo/zonas_extendidas_express.php';
require_once '../../modelo/precio_zona_extendida.php';
// require_once '../../modelo/cercania_almacen_odoo_cp.php';
require_once '../../modelo/almacenes_odoo.php';

class Envio
{
    public static function calculoEnvioOdooOrden($cp, $productos, $paqueteria)
    {

        if ($paqueteria == 'dhl') {
            $paqueteria = 'costo_dhl_odoo';
        }

        if ($paqueteria == 'express') {
            $paqueteria = 'costo_express_odoo';
        }

        if ($paqueteria == 'local') {
            $paqueteria = 'costo_local_odoo';
        }

        $estado_usuario = DireccionesSEPOMEX::mdlGetDireccionSEPOMEXByCP($cp);
        $almacenes_cercanos = CercaniaAlmacenOdoo::mdlGetCercaniaAlmacenOdooByEstado($estado_usuario[0]['d_estado']);

        $ids = array_map(function ($almacen) {
            // return intval($almacen['id_almacen_odoo']);
            return intval($almacen['id_odoo']);
        }, $almacenes_cercanos);

        $control_envio = array();
        //Este bloque de código verifica si puede salir de un mismo almacén todo el pedido
        // $productos_odoo = array_map(function ($producto) {
        //     return intval($producto['id_producto_odoo']);
        // }, $productos);

        // $productos_odoo_cantidad = array_map(function ($producto) {
        //     $aux_producto_cantidad['cantidad'] = $producto['cantidad'];
        //     $aux_producto_cantidad['id'] = intval($producto['id_producto_odoo']);
        //     return $aux_producto_cantidad;
        // }, $productos);

        $almacenes_stock_productos = OdooInventario::getWarehouseWithSufficientStock($ids, $productos);

        $total_productos = count($productos);

        $almacen_id = false;
        foreach ($almacenes_stock_productos as $almacen) {
            $almacen_id = false;

            $total_almacenes = count($almacen);

            if ($total_productos == $total_almacenes) {
                //Aquí se utiliza la primera posición ya que todos los objetos dentro de este arreglo tienen el mismo id de odoo
                $almacen_id = $almacen[0]['warehouse_id'];
                break;
            }
        }

        $key_warehouse = array_search($almacen_id, $ids);

        if ($key_warehouse !== false) {
            unset($ids[$key_warehouse]);
            array_unshift($ids, $almacen_id);
        }
        //Fin de este bloque de código
        foreach ($productos as $key => $producto) {
            $id_producto_odoo = $producto['id_producto_odoo'];
            $qty = intval($producto['cantidad']);

            $almacen_mas_cercano = OdooInventario::getStockByAlmacenId(intval($id_producto_odoo), intval($ids[0]));

            // echo json_encode('-------');
            // echo json_encode($producto);
            // echo json_encode('-------');
            // echo json_encode($almacen_mas_cercano);
            // echo json_encode('-------');

            if ($almacen_mas_cercano >= $qty) {
                $found = false;
                foreach ($control_envio as &$envio) {
                    if ($envio['almacen'] === intval($ids[0])) {
                        $peso = $producto['peso'] * $qty;
                        // $envio['nombre_almacen'] = $almacenes_cercanos[0]['nombre_almacen'];
                        $envio['almacen'] = intval($ids[0]);
                        $envio['productos'][] = array(
                            'id_producto_odoo' => $producto['id_producto_odoo'],
                            'id_producto' => $producto['id_producto'],
                            'id_precio' => $producto['id_precio'],
                            'cantidad' => $qty,
                            'peso' => round($producto['peso'] * $qty, 2)
                        );
                        $envio['peso_total'] += round($producto['peso'] * $qty, 2);
                        $found = true;
                        break;
                    }
                }

                if (!$found) {
                    $control_envio[] = array(
                        'peso_total' => round($producto['peso'] * $qty, 2),
                        'almacen' => intval($ids[0]),
                        // 'nombre_almacen' => $almacenes_cercanos[0]['nombre_almacen'],
                        'productos' => array(
                            array(
                                'id_producto_odoo' => $producto['id_producto_odoo'],
                                'id_producto' => $producto['id_producto'],
                                'id_precio' => $producto['id_precio'],
                                'cantidad' => $qty,
                                'peso' => round($producto['peso'] * $qty, 2)
                            )
                        ),
                    );
                }
            } else {

                $suma_almacenes = OdooInventario::getStockDistribution(intval($id_producto_odoo), $qty, $ids);

                foreach ($suma_almacenes as $almacen) {

                    $almacen_info = OdooInventario::getAlmacenInfoById($almacen['warehouse_id']);

                    $found = false;
                    foreach ($control_envio as &$envio) {
                        if ($envio['almacen'] === $almacen['warehouse_id']) {
                            // $envio['nombre_almacen'] = $almacen_info[0]['name'];
                            $envio['almacen'] = $almacen['warehouse_id'];
                            $envio['productos'][] = array(
                                'id_producto_odoo' => $producto['id_producto_odoo'],
                                'id_producto' => $producto['id_producto'],
                                'id_precio' => $producto['id_precio'],
                                'cantidad' => $almacen['quantity'],
                                'peso' => round($producto['peso'] * $almacen['quantity'], 2)
                            );
                            $envio['peso_total'] += round($producto['peso'] * $almacen['quantity'], 2);
                            $found = true;
                            break;
                        }
                    }

                    if (!$found) {
                        $control_envio[] = array(
                            'peso_total' => round($producto['peso'] * $almacen['quantity'], 2),
                            'almacen' => $almacen['warehouse_id'],
                            // 'nombre_almacen' => $almacen_info[0]['name'],
                            'productos' => array(
                                array(
                                    'id_producto_odoo' => $producto['id_producto_odoo'],
                                    'id_producto' => $producto['id_producto'],
                                    'id_precio' => $producto['id_precio'],
                                    'cantidad' => $almacen['quantity'],
                                    'peso' => round($producto['peso'] * $almacen['quantity'], 2)
                                )
                            ),
                        );
                    }
                }
            }
        }

        foreach ($control_envio as $key => $costo) {
            // if($costo['peso_total'] > 30 || !$paqueteria){
            //     $paqueteria = 'costo_express_odoo';
            // }

            // $info_envio = ModeloPesoEnvio::mdlGetCostosEnvio($costo['peso_total']);
            // $control_envio[$key]['id_producto_guia_envio'] = ($paqueteria != NULL) ? intval($info_envio[$paqueteria]) : NULL;

            $id_lot_stock = AlmacenesOdoo::mdlGetIdLotStock($costo['almacen']);

            $control_envio[$key]['id_lot_stock'] = $id_lot_stock['id_lot_stock'];
            $control_envio[$key]['id_tipo_picking'] = $id_lot_stock['id_tipo_picking'];
        }

        return $control_envio;
    }

    public static function calculoEnvioOdoo($cp, $productos, $paqueteria)
    {
        if ($paqueteria == 'DHL') {
            $paqueteria = 'costo_dhl_odoo';
        }

        if ($paqueteria == 'Express') {
            $paqueteria = 'costo_express_odoo';
        }

        if ($paqueteria == 'Local') {
            $paqueteria = 'costo_local_odoo';
        }

        $estado_usuario = DireccionesSEPOMEX::mdlGetDireccionSEPOMEXByCP($cp);
        $almacenes_cercanos = CercaniaAlmacenOdoo::mdlGetCercaniaAlmacenOdooByEstado($estado_usuario[0]['d_estado']);

        $ids = array_map(function ($almacen) {
            // return intval($almacen['id_almacen_odoo']);
            return intval($almacen['id_odoo']);
        }, $almacenes_cercanos);

        // Este es el arreglo para saber los nombres de los almacenes, el de arriba es para saber los id's de odoo
        $almacenes_mas_cercanos = array_map(function ($almacenes_cercanos) {
            return $almacenes_cercanos['codigo_almacen'];
        }, $almacenes_cercanos);

        $control_envio = array();
        $total_productos = count($productos);
        $aux_contador = 0;
        $aux_contador_republica = 0;

        $productos_odoo = array_map(function ($producto) {
            return intval($producto['id_producto_odoo']);
        }, $productos);

        $productos_odoo_cantidad = array_map(function ($producto) {
            $aux_producto_cantidad['cantidad'] = $producto['cantidad'];
            $aux_producto_cantidad['id'] = intval($producto['id_producto_odoo']);
            return $aux_producto_cantidad;
        }, $productos);

        $almacenes_stock_productos = OdooInventario::getWarehouseWithSufficientStock($ids, $productos);

        $total_productos = count($productos);

        $almacen_id = false;
        foreach ($almacenes_stock_productos as $almacen) {
            $almacen_id = false;

            $total_almacenes = count($almacen);

            if ($total_productos == $total_almacenes) {
                //Aquí se utiliza la primera posición ya que todos los objetos dentro de este arreglo tienen el mismo id de odoo
                $almacen_id = $almacen[0]['warehouse_id'];
                break;
            }
        }

        $key = array_search($almacen_id, $ids);

        if ($key !== false) {
            unset($ids[$key]);
            array_unshift($ids, $almacen_id);
        }

        foreach ($productos as $producto) {
            $id_producto_odoo = intval($producto['id_producto_odoo']);
            $productos_odoo[] = $id_producto_odoo;
            $productos_odoo_cantidad[] = array(
                'cantidad' => $producto['cantidad'],
                'id' => $id_producto_odoo
            );

            $qty = intval($producto['cantidad']);

            $almacen_mas_cercano = OdooInventario::getStockByAlmacenId(intval($id_producto_odoo), intval($ids[0]));

            $cercania_almacen_republica = CercaniaAlmacenOdooCP::mdlValidateUbicacionAlmacenCP($ids[0], $cp);

            if ($almacen_mas_cercano >= $qty) {
                $peso = $producto['peso'] * $qty;

                $info_envio = ModeloPesoEnvio::mdlGetCostosEnvio($peso);

                $found = false;

                // Check if the warehouse is Algarin or Matriz and if the CP is in CDMX
                if (($almacenes_mas_cercanos[0] === 'ALG' || $almacenes_mas_cercanos[0] === 'MAT') && $estado_usuario[0]['d_estado'] === 'Ciudad de México') {
                    $aux_contador++;
                }


                if ($cercania_almacen_republica !== false) {
                    $aux_contador_republica++;
                }

                // echo json_encode('---------');
                // // echo json_encode($ids);
                // // echo json_encode($cp);
                // echo json_encode($cercania_almacen_republica);
                // echo json_encode('---------');
                
                // if (($almacenes_mas_cercanos[0] === 'ALG' || $almacenes_mas_cercanos[0] === 'MAT') || ($almacenes_mas_cercanos[1] === 'ALG' || $almacenes_mas_cercanos[1] === 'MAT') && $estado_usuario[0]['d_estado'] === 'Ciudad de México') {
                //     $aux_contador++;
                // }

                // Aqui se hace un arreglo con los datos del envío local pero es necesario ponerlo como una opcion adicional, no como predeterminada
                // if($aux_contador === $total_productos){
                //     $control_envio_local[] = array(
                //         'cantidad' => $qty,
                //         'peso' => round($producto['peso'] * $qty, 2),
                //         'id_producto_guia_envio' => ($paqueteria != NULL) ? intval($info_envio['costo_local_odoo']) : NULL,
                //         // 'id_producto_guia_envio' => ($paqueteria != NULL) ? intval(5) : NULL,
                //         'almacen' => intval($ids[0]),
                //         'id_producto' => $producto['id_producto_odoo']
                //     );
                // }

                foreach ($control_envio as &$envio) {
                    if ($envio['almacen'] === intval($ids[0])) {
                        $envio['cantidad'] += $qty;
                        $envio['dimensiones']['peso'] += round($peso, 2);
                        // $envio['volumen'] += $producto['alto'] * $producto['ancho'] * $producto['largo'] * $qty;
                        $envio['dimensiones']['alto'] += $producto['alto'] * $qty;
                        $envio['dimensiones']['ancho'] += $producto['ancho'] * $qty;
                        $envio['dimensiones']['largo'] += $producto['largo'] * $qty;
                        // $envio['id_producto_guia_envio'] = ($paqueteria != NULL) ? intval($info_envio[$paqueteria]) : NULL;
                        $envio['almacen'] = intval($ids[0]);
                        $envio['id_producto'] = $producto['id_producto_odoo'];
                        $found = true;
                        break;
                    }
                }

                if (!$found) {

                    $control_envio[] = array(
                        'cantidad' => $qty,
                        // 'volumen' => $producto['alto'] * $producto['ancho'] * $producto['largo'] * $qty,
                        'dimensiones' => array(
                            'peso' => round($peso, 2),
                            'alto' => $producto['alto'] * $qty,
                            'ancho' => $producto['ancho'] * $qty,
                            'largo' => $producto['largo'] * $qty
                        ),
                        // 'id_producto_guia_envio' => ($paqueteria != NULL) ? intval($info_envio[$paqueteria]) : NULL,
                        'almacen' => intval($ids[0]),
                        'id_producto' => $producto['id_producto_odoo']
                    );
                }
            } else {
                $suma_almacenes = OdooInventario::getStockDistribution($id_producto_odoo, $qty, $ids);

                foreach ($suma_almacenes as $key => $almacen) {

                    $peso = $producto['peso'] * $almacen['quantity'];

                    $info_envio = ModeloPesoEnvio::mdlGetCostosEnvio($peso);

                    $found = false;
                    foreach ($control_envio as &$envio) {


                        if ($envio['almacen'] === $almacen['warehouse_id']) {
                            $envio['cantidad'] += $almacen['quantity'];
                            $envio['dimensiones']['peso'] += round($peso, 2);
                            // $envio['volumen'] += $producto['alto'] * $producto['ancho'] * $producto['largo'] * $qty;
                            $envio['dimensiones']['alto'] += $producto['alto'] * $qty;
                            $envio['dimensiones']['ancho'] += $producto['ancho'] * $qty;
                            $envio['dimensiones']['largo'] += $producto['largo'] * $qty;
                            // $envio['id_producto_guia_envio'] = ($paqueteria != NULL) ? intval($info_envio[$paqueteria]) : NULL;
                            $envio['almacen'] = $almacen['warehouse_id'];
                            $envio['id_producto'] = $producto['id_producto_odoo'];
                            $found = true;
                            break;
                        }
                    }

                    if (!$found) {
                        $control_envio[] = array(
                            'cantidad' => $almacen['quantity'],
                            'peso' => round($peso, 2),
                            // 'volumen' => $producto['alto'] * $producto['ancho'] * $producto['largo'] * $qty,
                            'dimensiones' => array(
                                'peso' => round($peso, 2),
                                'alto' => $producto['alto'] * $qty,
                                'ancho' => $producto['ancho'] * $qty,
                                'largo' => $producto['largo'] * $qty
                            ),
                            // 'id_producto_guia_envio' => ($paqueteria != NULL) ? intval($info_envio[$paqueteria]) : NULL,
                            'almacen' => $almacen['warehouse_id'],
                            'id_producto' => $producto['id_producto_odoo']
                        );
                    }
                }
            }
        }

        $control_envio[0]['entrega_local'] = false;

        if ($aux_contador === $total_productos) {
            $control_envio[0]['entrega_local'] = true;
        }

        $control_envio[0]['recoleccion_local'] = false;

        if($aux_contador_republica === $total_productos){
            $control_envio[0]['recoleccion_local'] = true;
        }
        return $control_envio;
    }

    public static function getCostoEnvioCarrito($cp, $productos)
    {
        $control_envio = self::calculoEnvioOdoo($cp, $productos, NULL);

        // $costo_envio = CostosPaqueteria::costoEnvioCarrito(array_column($control_envio, 'peso'));
        $costo_envio = CostosPaqueteria::costoPak2Go($control_envio, $cp);

        // if (ZonaExtendidaExpress::mdlIsZonaExtendidaExpress($cp)) {
        //     $precio_zona_extendida = PrecioZonaExtendida::mdlGetPrecioZonaExtendidaByNombre('Express');
        //     $costo_zona_extendida = $precio_zona_extendida['precio'] * count($control_envio);
        //     $costo_envio += $costo_zona_extendida;
        //     $control_envio[0]['id_zona_extendida_odoo'] = $precio_zona_extendida['id_precio_odoo'];
        // }

        return $costo_envio;
    }
    // En estos dos modelos necesito validar si la entrega es en area etropolitana y la compra mayor a 4k el envio es gratis.
    // Si la entrega es area metro la entrega es por paqueteria local
    public static function getPaqueteriasCheckout($cp, $productos)
    {
        $control_envio = self::calculoEnvioOdoo($cp, $productos, NULL);
        // echo json_encode($control_envio);
        $costo_envio = CostosPaqueteria::costoPak2Go($control_envio, $cp);

        if ($control_envio[0]['entrega_local']) {
            $costo_envio["ENTREGA LOCAL"] = array(
                'amount_local' => 99.00,
                'currency_local' => 'MXN',
                'provider' => 'MTM',
                'service_level_name' => 'Local',
                'service_level_code' => 'STANDARD',
                'days' => 5,
                'insurable' => '',
                'out_of_area_service' => false,
                'out_of_area_pricing' => false,
                'total_pricing' => 99.00
            );
        }

        if ($control_envio[0]['recoleccion_local']) {
            $costo_envio["ENTREGA SUCURSAL"] = array(
                'amount_local' => '0.00',
                'currency_local' => 'MXN',
                'provider' => 'ENTREGA SUCURSAL',
                'service_level_name' => 'Local',
                'service_level_code' => 'STANDARD',
                'days' => 5,
                'insurable' => '',
                'out_of_area_service' => false,
                'out_of_area_pricing' => false,
                'total_pricing' => 0.00
            );
        }

        return $costo_envio;
    }

    public static function getOrdenOdoo($cp, $productos, $paqueteria)
    {
        $response = array();
        $control_envio = self::calculoEnvioOdooOrden($cp, $productos, $paqueteria);

        // $response['zona_extendida'] = array();

        // if (ZonaExtendidaExpress::mdlIsZonaExtendidaExpress($cp) && $paqueteria == 'express') {
        //     // Condition is true
        //     $precio_zona_extendida = PrecioZonaExtendida::mdlGetPrecioZonaExtendidaByNombre('Express');
        //     $response['zona_extendida']['zona_extendida_cantidad'] = count($control_envio);
        //     $response['zona_extendida']['id_zona_extendida_odoo'] = $precio_zona_extendida['id_precio_odoo'];
        // }

        // if (ZonaExtendidaExpress::mdlIsZonaExtendidaDHL($cp) && $paqueteria == 'dhl') {
        //     // Condition is true
        //     $precio_zona_extendida = PrecioZonaExtendida::mdlGetPrecioZonaExtendidaByNombre('DHL');
        //     $response['zona_extendida']['zona_extendida_cantidad'] = count($control_envio);
        //     $response['zona_extendida']['id_zona_extendida_odoo'] = $precio_zona_extendida['id_precio_odoo'];
        // }

        $response['control_envio'] = $control_envio;
        return $response;
    }
}
