<?php
/**
 * API: Sincronizar y actualizar producto maestro y mapear descripción FEL
 * POST: JSON input
 */
header('Content-Type: application/json; charset=utf-8');
require_once __DIR__ . '/../config/db.php';

try {
    $input = json_decode(file_get_contents('php://input') ?: ($GLOBALS['MOCK_INPUT'] ?? ''), true);

    if (!$input || !isset($input['producto_id']) || !isset($input['descripcion_factura'])) {
        throw new Exception('Faltan datos obligatorios para sincronizar');
    }

    $pdo = getConnection();
    $pdo->beginTransaction();

    $pid = intval($input['producto_id']);
    $descFactura = trim($input['descripcion_factura']);
    
    $f_blister = intval($input['FactorBlister'] ?? 1);
    $f_caja = intval($input['FactorCaja'] ?? 1);
    $exento = !empty($input['esExento']) ? 1 : 0;
    $c_unidad = floatval($input['costo_unidad'] ?? 0);

    // --- 1. Actualizar tabla maestra: productos ---
    $sqlProd = "UPDATE productos SET 
                    exento_iva = :exento
                WHERE id = :id";
    
    $stmtProd = $pdo->prepare($sqlProd);
    $stmtProd->execute([
        ':exento' => $exento,
        ':id'     => $pid
    ]);

    // --- 2. Sincronizar tabla producto_presentaciones ---
    if (!empty($input['presentaciones']) && is_array($input['presentaciones'])) {
        // --- PROCESADO DINÁMICO DE PRESENTACIONES ---
        $presentaciones = $input['presentaciones'];

        $basePres = $presentaciones[0] ?? [
            'presentacion_id' => 1,
            'factor_conversion' => 1,
            'activo' => 1,
            'precio_venta' => 0.0,
            'margen_ganancia_porcentaje' => 30.0
        ];

        $basePresId = intval($basePres['presentacion_id']);
        $baseActivo = intval($basePres['activo']);
        $basePrecio = floatval($basePres['precio_venta']);
        $baseMargen = floatval($basePres['margen_ganancia_porcentaje']);

        // Reset es_unidad_base a 0 primero
        $clearBaseFlag = $pdo->prepare("UPDATE producto_presentaciones SET es_unidad_base = 0 WHERE producto_id = :pId");
        $clearBaseFlag->execute([':pId' => $pid]);

        // Desactivar temporalmente todas las que no sean la base seleccionada
        $deactivate = $pdo->prepare("UPDATE producto_presentaciones SET activo = 0 WHERE producto_id = :pId AND presentacion_id != :basePresId");
        $deactivate->execute([':pId' => $pid, ':basePresId' => $basePresId]);

        // Guardar/Actualizar la presentación base
        $checkBase = $pdo->prepare("SELECT id FROM producto_presentaciones WHERE producto_id = :pId AND presentacion_id = :basePresId");
        $checkBase->execute([':pId' => $pid, ':basePresId' => $basePresId]);

        if ($checkBase->rowCount() > 0) {
            $updBase = $pdo->prepare("UPDATE producto_presentaciones 
                                      SET factor_conversion = 1, activo = :activo, es_unidad_base = 1, 
                                          precio_venta = :precio, margen_ganancia_porcentaje = :margen, 
                                          fecha_actualizacion = NOW() 
                                      WHERE producto_id = :pId AND presentacion_id = :basePresId");
            $updBase->execute([
                ':activo' => $baseActivo,
                ':precio' => $basePrecio,
                ':margen' => $baseMargen,
                ':pId' => $pid,
                ':basePresId' => $basePresId
            ]);
        } else {
            $insBase = $pdo->prepare("INSERT INTO producto_presentaciones 
                                      (producto_id, presentacion_id, factor_conversion, activo, es_unidad_base, orden, precio_venta, margen_ganancia_porcentaje, es_facturable, es_comprable, es_vendible, fecha_creacion) 
                                      VALUES (:pId, :basePresId, 1, :activo, 1, 1, :precio, :margen, 1, 1, 1, NOW())");
            $insBase->execute([
                ':pId' => $pid,
                ':basePresId' => $basePresId,
                ':activo' => $baseActivo,
                ':precio' => $basePrecio,
                ':margen' => $baseMargen
            ]);
        }

        // Insertar o actualizar las otras presentaciones
        $orden = 2;
        foreach ($presentaciones as $idx => $pres) {
            if ($idx === 0) continue; // Ya procesada la base

            $presId = (int)$pres['presentacion_id'];
            if ($presId === $basePresId) continue;

            $factor = (int)$pres['factor_conversion'];
            $activo = (int)$pres['activo'];
            $precio = (float)$pres['precio_venta'];
            $margen = (float)$pres['margen_ganancia_porcentaje'];

            if ($factor <= 0) $factor = 1;

            $checkEx = $pdo->prepare("SELECT id FROM producto_presentaciones WHERE producto_id = :pId AND presentacion_id = :presId");
            $checkEx->execute([':pId' => $pid, ':presId' => $presId]);

            if ($checkEx->rowCount() > 0) {
                $updPres = $pdo->prepare("UPDATE producto_presentaciones 
                                          SET factor_conversion = :factor, activo = :activo, 
                                              precio_venta = :precio, margen_ganancia_porcentaje = :margen, 
                                              orden = :orden, fecha_actualizacion = NOW() 
                                          WHERE producto_id = :pId AND presentacion_id = :presId");
                $updPres->execute([
                    ':factor' => $factor,
                    ':activo' => $activo,
                    ':precio' => $precio,
                    ':margen' => $margen,
                    ':orden' => $orden,
                    ':pId' => $pid,
                    ':presId' => $presId
                ]);
            } else {
                $insPres = $pdo->prepare("INSERT INTO producto_presentaciones 
                                          (producto_id, presentacion_id, factor_conversion, activo, es_unidad_base, orden, precio_venta, margen_ganancia_porcentaje, es_facturable, es_comprable, es_vendible, fecha_creacion) 
                                          VALUES (:pId, :presId, :factor, :activo, 0, :orden, :precio, :margen, 1, 1, 1, NOW())");
                $insPres->execute([
                    ':pId' => $pid,
                    ':presId' => $presId,
                    ':factor' => $factor,
                    ':activo' => $activo,
                    ':precio' => $precio,
                    ':margen' => $margen,
                    ':orden' => $orden
                ]);
            }
            $orden++;
        }
    } else {
        // --- PROCESADO LEGACY (COMPATIBILIDAD) ---
        $stmtPres = $pdo->prepare("
            INSERT INTO producto_presentaciones 
                (producto_id, presentacion_id, factor_conversion, precio_venta, activo, es_unidad_base, es_facturable, es_comprable, es_vendible, fecha_creacion, fecha_actualizacion) 
            VALUES 
                (:pid, :pres, :factor, :precio, :activo, :es_base, 1, 1, 1, NOW(), NOW()) 
            ON DUPLICATE KEY UPDATE 
                factor_conversion = :factor2, 
                precio_venta = :precio2, 
                activo = :activo2, 
                fecha_actualizacion = NOW()
        ");

        // Sincronizar Unidad
        $stmtPres->execute([
            ':pid'     => $pid,
            ':pres'    => 1,
            ':factor'  => 1,
            ':precio'  => floatval($input['PrecioVentaUnidad'] ?? 0),
            ':activo'  => 1,
            ':es_base' => 1,
            ':factor2' => 1,
            ':precio2' => floatval($input['PrecioVentaUnidad'] ?? 0),
            ':activo2' => 1
        ]);

        // Sincronizar Blíster
        $stmtPres->execute([
            ':pid'     => $pid,
            ':pres'    => 2,
            ':factor'  => $f_blister,
            ':precio'  => floatval($input['PrecioVentaBlister'] ?? 0),
            ':activo'  => ($f_blister > 1) ? 1 : 0,
            ':es_base' => 0,
            ':factor2' => $f_blister,
            ':precio2' => floatval($input['PrecioVentaBlister'] ?? 0),
            ':activo2' => ($f_blister > 1) ? 1 : 0
        ]);

        // Sincronizar Caja
        $stmtPres->execute([
            ':pid'     => $pid,
            ':pres'    => 3,
            ':factor'  => $f_caja,
            ':precio'  => floatval($input['PrecioVentaMayor'] ?? 0),
            ':activo'  => ($f_caja > 1) ? 1 : 0,
            ':es_base' => 0,
            ':factor2' => $f_caja,
            ':precio2' => floatval($input['PrecioVentaMayor'] ?? 0),
            ':activo2' => ($f_caja > 1) ? 1 : 0
        ]);
    }

    // --- 3. Actualizar/Insertar en producto_lugares_compra ---
    $lugarId = intval($input['lugar_compra_id'] ?? 1);
    
    // Función para normalizar fecha a YYYY-MM-DD
    $normalizarFecha = function($raw) {
        if (!$raw) return date('Y-m-d');
        $raw = trim($raw);
        // Caso DD-MM-YYYY o DD/MM/YYYY
        if (preg_match('/^(\d{1,2})[-|\/](\d{1,2})[-|\/](\d{4})/', $raw, $m)) {
            return "{$m[3]}-" . str_pad($m[2], 2, '0', STR_PAD_LEFT) . "-" . str_pad($m[1], 2, '0', STR_PAD_LEFT);
        }
        // Caso YYYY-MM-DD
        if (preg_match('/^(\d{4})[-|\/](\d{1,2})[-|\/](\d{1,2})/', $raw, $m)) {
            return "{$m[1]}-" . str_pad($m[2], 2, '0', STR_PAD_LEFT) . "-" . str_pad($m[3], 2, '0', STR_PAD_LEFT);
        }
        return date('Y-m-d');
    };

    $fechaFacturaRaw = $input['fecha_factura'] ?? '';
    $fechaSql = $normalizarFecha($fechaFacturaRaw);
    $fechaVencRaw = $input['FechaVencimiento'] ?? null;
    $fechaVencimiento = $fechaVencRaw ? $normalizarFecha($fechaVencRaw) : null;
    $conFactura = !empty($input['conFactura']) ? 1 : 0;

    $upsertLugar = function($pdo, $pid, $lid, $costo, $fecha, $fechaVenc, $conFact, $exento) {
        $stmt = $pdo->prepare("SELECT id FROM producto_lugares_compra WHERE producto_id = :pid AND lugar_compra_id = :lid AND fecha_ultima_compra = :fecha");
        $stmt->execute([':pid' => $pid, ':lid' => $lid, ':fecha' => $fecha]);
        $row = $stmt->fetch();
        
        if ($row) {
            $stmtUpdate = $pdo->prepare("
                UPDATE producto_lugares_compra SET
                    costo_compra = :costo,
                    fecha_ultima_compra = :fecha,
                    fecha_vencimiento = :fecha_venc,
                    con_factura = :con_fact,
                    exento_iva = :exento,
                    fecha_actualizacion = NOW(),
                    activo = 1
                WHERE id = :id
            ");
            $stmtUpdate->execute([
                ':costo'      => $costo,
                ':fecha'      => $fecha,
                ':fecha_venc' => $fechaVenc,
                ':con_fact'   => $conFact,
                ':exento'     => $exento,
                ':id'         => $row['id']
            ]);
        } else {
            $stmtInsert = $pdo->prepare("
                INSERT INTO producto_lugares_compra
                    (producto_id, lugar_compra_id, costo_compra, fecha_ultima_compra, fecha_vencimiento, con_factura, exento_iva, activo, fecha_creacion, fecha_actualizacion)
                VALUES
                    (:pid, :lid, :costo, :fecha, :fecha_venc, :con_fact, :exento, 1, NOW(), NOW())
            ");
            $stmtInsert->execute([
                ':pid'        => $pid,
                ':lid'        => $lid,
                ':costo'      => $costo,
                ':fecha'      => $fecha,
                ':fecha_venc' => $fechaVenc,
                ':con_fact'   => $conFact,
                ':exento'     => $exento
            ]);
        }
    };

    // Upsert General (lugar_id = 1)
    $upsertLugar($pdo, $pid, 1, $c_unidad, $fechaSql, $fechaVencimiento, $conFactura, $exento);

    // Upsert específico si es diferente de General
    if ($lugarId && $lugarId !== 1) {
        $upsertLugar($pdo, $pid, $lugarId, $c_unidad, $fechaSql, $fechaVencimiento, $conFactura, $exento);
    }

    // --- 4. Sincronizar en productos_costo_promedio (CPP) ---
    $stmtCheckCPP = $pdo->prepare("SELECT id, cantidad_total_unidades FROM productos_costo_promedio WHERE producto_id = :pid");
    $stmtCheckCPP->execute([':pid' => $pid]);
    $cppRow = $stmtCheckCPP->fetch();

    if ($cppRow) {
        $qty = intval($cppRow['cantidad_total_unidades'] ?? 0);
        $nuevoValorTotal = round($c_unidad * $qty, 2);
        
        $stmtUpdateCPP = $pdo->prepare("
            UPDATE productos_costo_promedio SET
                costo_promedio_unidad_base = :costo,
                valor_total_inventario = :valor,
                fecha_ultimo_calculo = NOW()
            WHERE id = :id
        ");
        $stmtUpdateCPP->execute([
            ':costo' => $c_unidad,
            ':valor' => $nuevoValorTotal,
            ':id'    => $cppRow['id']
        ]);
    } else {
        $stmtInsertCPP = $pdo->prepare("
            INSERT INTO productos_costo_promedio
                (producto_id, costo_promedio_unidad_base, cantidad_total_unidades, valor_total_inventario, fecha_creacion)
            VALUES
                (:pid, :costo, 0, 0.00, NOW())
        ");
        $stmtInsertCPP->execute([
            ':pid'   => $pid,
            ':costo' => $c_unidad
        ]);
    }

    // --- 5. Guardar/Actualizar Mapeo FEL ---
    if (empty($input['skip_fel_mapping'])) {
        $stmtMap = $pdo->prepare("
            INSERT INTO fel_producto_mapping (descripcion_factura, producto_id) 
            VALUES (:desc, :pid) 
            ON DUPLICATE KEY UPDATE producto_id = :pid2, fecha_mapeo = NOW()
        ");
        $stmtMap->execute([
            ':desc' => $descFactura,
            ':pid'  => $pid,
            ':pid2' => $pid
        ]);
    }

    $pdo->commit();
    echo json_encode(['success' => true, 'message' => 'Producto sincronizado y mapeado correctamente']);

} catch (Exception $e) {
    if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack();
    http_response_code(500);
    echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
