<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');

$user = requireAuth();

switch ($tipo) {
    case 'getCotizaciones':
        try {
            $page = max(1, intval($datapost['page'] ?? $_GET['page'] ?? 1));
            $limit = max(1, min(100, intval($datapost['limit'] ?? $_GET['limit'] ?? 20)));
            $offset = ($page - 1) * $limit;
            $estado = trim($datapost['estado'] ?? $_GET['estado'] ?? '');

            $where = "WHERE cot.usuario_id = ? AND cot.activo = 1";
            $params = [$user['id']];
            $types = "i";

            if (!empty($estado)) {
                $where .= " AND cot.estado = ?";
                $params[] = $estado;
                $types .= "s";
            }

            // Contar total
            $countQuery = "SELECT COUNT(*) as total FROM cotizaciones cot $where";
            $countStmt = $conn->prepare($countQuery);
            $countStmt->bind_param($types, ...$params);
            $countStmt->execute();
            $total = $countStmt->get_result()->fetch_assoc()['total'];

            // Obtener cotizaciones
            $query = "SELECT
                cot.id,
                cot.folio,
                cot.cliente_id,
                cot.cliente_nombre,
                cot.subtotal,
                cot.impuesto,
                cot.descuento,
                cot.total,
                cot.estado,
                cot.vigencia,
                cot.observaciones,
                cot.fecha_creacion,
                COUNT(cd.id) as total_productos
            FROM cotizaciones cot
            LEFT JOIN cotizacion_detalles cd ON cot.id = cd.cotizacion_id
            $where
            GROUP BY cot.id
            ORDER BY cot.fecha_creacion DESC
            LIMIT ? OFFSET ?";

            $params[] = $limit;
            $params[] = $offset;
            $types .= "ii";

            $stmt = $conn->prepare($query);
            $stmt->bind_param($types, ...$params);
            $stmt->execute();
            $result = $stmt->get_result();

            $cotizaciones = [];
            while ($row = $result->fetch_assoc()) {
                $cotizaciones[] = [
                    'id' => intval($row['id']),
                    'folio' => $row['folio'],
                    'cliente_id' => $row['cliente_id'] ? intval($row['cliente_id']) : null,
                    'cliente_nombre' => $row['cliente_nombre'] ?? 'Sin cliente',
                    'subtotal' => floatval($row['subtotal']),
                    'impuesto' => floatval($row['impuesto']),
                    'descuento' => floatval($row['descuento']),
                    'total' => floatval($row['total']),
                    'estado' => $row['estado'],
                    'vigencia' => $row['vigencia'],
                    'observaciones' => $row['observaciones'],
                    'total_productos' => intval($row['total_productos']),
                    'fecha_creacion' => $row['fecha_creacion']
                ];
            }

            sendPaginatedResponse(true, "Cotizaciones obtenidas", $cotizaciones, $total, $page, $limit);

        } catch (Exception $e) {
            sendResponse(false, "Error al obtener cotizaciones: " . $e->getMessage());
        }
        break;

    case 'getCotizacion':
        $id = intval($datapost['id'] ?? $_GET['id'] ?? 0);

        if ($id <= 0) {
            sendResponse(false, "ID de cotización requerido");
        }

        try {
            $query = "SELECT
                cot.id, cot.folio, cot.cliente_id, cot.cliente_nombre,
                cot.usuario_id, cot.usuario_nombre,
                cot.subtotal, cot.impuesto, cot.descuento, cot.total,
                cot.estado, cot.vigencia, cot.observaciones,
                cot.fecha_creacion, cot.fecha_actualizacion
            FROM cotizaciones cot
            WHERE cot.id = ? AND cot.activo = 1";

            $stmt = $conn->prepare($query);
            $stmt->bind_param("i", $id);
            $stmt->execute();
            $result = $stmt->get_result();

            if ($row = $result->fetch_assoc()) {
                // Obtener detalles
                $detQuery = "SELECT
                    cd.id, cd.producto_id, cd.producto_nombre, cd.cantidad,
                    cd.precio_unitario, cd.subtotal, cd.impuesto, cd.descuento, cd.total,
                    cd.precio_tipo,
                    p.codigo_corto, p.codigo_barras, p.stock
                FROM cotizacion_detalles cd
                LEFT JOIN productos p ON cd.producto_id = p.id
                WHERE cd.cotizacion_id = ?
                ORDER BY cd.id ASC";

                $detStmt = $conn->prepare($detQuery);
                $detStmt->bind_param("i", $id);
                $detStmt->execute();
                $detResult = $detStmt->get_result();

                $detalles = [];
                while ($det = $detResult->fetch_assoc()) {
                    $detalles[] = [
                        'id' => intval($det['id']),
                        'producto_id' => intval($det['producto_id']),
                        'producto_nombre' => $det['producto_nombre'],
                        'codigo_corto' => $det['codigo_corto'],
                        'codigo_barras' => $det['codigo_barras'],
                        'cantidad' => floatval($det['cantidad']),
                        'precio_unitario' => floatval($det['precio_unitario']),
                        'subtotal' => floatval($det['subtotal']),
                        'impuesto' => floatval($det['impuesto']),
                        'descuento' => floatval($det['descuento']),
                        'total' => floatval($det['total']),
                        'precio_tipo' => $det['precio_tipo'],
                        'stock_actual' => $det['stock'] !== null ? floatval($det['stock']) : null
                    ];
                }

                $cotizacion = [
                    'id' => intval($row['id']),
                    'folio' => $row['folio'],
                    'cliente_id' => $row['cliente_id'] ? intval($row['cliente_id']) : null,
                    'cliente_nombre' => $row['cliente_nombre'],
                    'usuario_id' => intval($row['usuario_id']),
                    'usuario_nombre' => $row['usuario_nombre'],
                    'subtotal' => floatval($row['subtotal']),
                    'impuesto' => floatval($row['impuesto']),
                    'descuento' => floatval($row['descuento']),
                    'total' => floatval($row['total']),
                    'estado' => $row['estado'],
                    'vigencia' => $row['vigencia'],
                    'observaciones' => $row['observaciones'],
                    'detalles' => $detalles,
                    'fecha_creacion' => $row['fecha_creacion'],
                    'fecha_actualizacion' => $row['fecha_actualizacion']
                ];

                sendResponse(true, "Cotización obtenida exitosamente", $cotizacion);
            } else {
                sendResponse(false, "Cotización no encontrada");
            }

        } catch (Exception $e) {
            sendResponse(false, "Error al obtener cotización: " . $e->getMessage());
        }
        break;

    case 'crearCotizacion':
        $cliente_id = isset($datapost['cliente_id']) && $datapost['cliente_id'] ? intval($datapost['cliente_id']) : null;
        $cliente_nombre = trim($datapost['cliente_nombre'] ?? 'Sin cliente');
        $observaciones = trim($datapost['observaciones'] ?? '');
        $vigencia = $datapost['vigencia'] ?? date('Y-m-d', strtotime('+7 days'));
        $productos = $datapost['productos'] ?? [];

        if (empty($productos) || !is_array($productos)) {
            sendResponse(false, "Debe agregar al menos un producto");
        }

        try {
            $conn->begin_transaction();

            // Calcular totales
            $subtotal = 0;
            $descuento = 0;
            $impuesto = 0;

            foreach ($productos as $prod) {
                $cantidad = floatval($prod['cantidad'] ?? 0);
                $precio = floatval($prod['precio_unitario'] ?? 0);
                $subtotal += $cantidad * $precio;
                $descuento += floatval($prod['descuento'] ?? 0);
                $impuesto += floatval($prod['impuesto'] ?? 0);
            }

            $total = $subtotal - $descuento + $impuesto;

            // Generar folio
            $folio = 'COT-' . date('Ymd') . '-' . str_pad(rand(1, 9999), 4, '0', STR_PAD_LEFT);
            $checkStmt = $conn->prepare("SELECT id FROM cotizaciones WHERE folio = ?");
            $checkStmt->bind_param("s", $folio);
            $checkStmt->execute();
            while ($checkStmt->get_result()->num_rows > 0) {
                $folio = 'COT-' . date('Ymd') . '-' . str_pad(rand(1, 9999), 4, '0', STR_PAD_LEFT);
                $checkStmt->bind_param("s", $folio);
                $checkStmt->execute();
            }

            $usuario_id = $user['id'];
            $usuario_nombre = $user['nombre'];
            $estado = 'pendiente';
            $activo = 1;

            $insertQuery = "INSERT INTO cotizaciones (
                folio, cliente_id, cliente_nombre, usuario_id, usuario_nombre,
                subtotal, impuesto, descuento, total, estado, vigencia, observaciones, activo
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

            $stmt = $conn->prepare($insertQuery);
            $stmt->bind_param(
                "sisisddddssi",
                $folio, $cliente_id, $cliente_nombre, $usuario_id, $usuario_nombre,
                $subtotal, $impuesto, $descuento, $total, $estado, $vigencia, $observaciones, $activo
            );

            if (!$stmt->execute()) {
                $conn->rollback();
                sendResponse(false, "Error al crear cotización: " . $stmt->error);
            }

            $cotizacion_id = $conn->insert_id;

            // Insertar detalles
            $detQuery = "INSERT INTO cotizacion_detalles (
                cotizacion_id, producto_id, producto_nombre, cantidad,
                precio_unitario, subtotal, impuesto, descuento, total, precio_tipo
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

            $detStmt = $conn->prepare($detQuery);

            foreach ($productos as $prod) {
                $producto_id = intval($prod['producto_id']);
                $producto_nombre = trim($prod['producto_nombre']);
                $cantidad = floatval($prod['cantidad']);
                $precio_unitario = floatval($prod['precio_unitario']);
                $desc_prod = floatval($prod['descuento'] ?? 0);
                $imp_prod = floatval($prod['impuesto'] ?? 0);
                $precio_tipo = trim($prod['precio_tipo'] ?? 'precio1');

                $subtotal_prod = $cantidad * $precio_unitario;
                $total_prod = $subtotal_prod - $desc_prod + $imp_prod;

                $detStmt->bind_param(
                    "iisdddddds",
                    $cotizacion_id, $producto_id, $producto_nombre, $cantidad,
                    $precio_unitario, $subtotal_prod, $imp_prod, $desc_prod, $total_prod, $precio_tipo
                );

                if (!$detStmt->execute()) {
                    $conn->rollback();
                    sendResponse(false, "Error al guardar detalle de cotización");
                }
            }

            $conn->commit();
            sendResponse(true, "Cotización creada exitosamente", ['id' => $cotizacion_id, 'folio' => $folio]);

        } catch (Exception $e) {
            $conn->rollback();
            sendResponse(false, "Error al crear cotización: " . $e->getMessage());
        }
        break;

    case 'actualizarCotizacion':
        $id = intval($datapost['id'] ?? 0);
        $observaciones = isset($datapost['observaciones']) ? trim($datapost['observaciones']) : null;
        $vigencia = $datapost['vigencia'] ?? null;
        $productos = $datapost['productos'] ?? null;

        if ($id <= 0) {
            sendResponse(false, "ID de cotización requerido");
        }

        try {
            $checkStmt = $conn->prepare("SELECT estado FROM cotizaciones WHERE id = ? AND activo = 1");
            $checkStmt->bind_param("i", $id);
            $checkStmt->execute();
            $checkResult = $checkStmt->get_result();

            if ($checkResult->num_rows === 0) {
                sendResponse(false, "Cotización no encontrada");
            }

            $cot = $checkResult->fetch_assoc();
            if ($cot['estado'] === 'convertida') {
                sendResponse(false, "No se puede editar una cotización ya convertida a pedido");
            }

            $conn->begin_transaction();

            // Actualizar campos básicos
            $updates = [];
            $params = [];
            $types = "";

            if ($observaciones !== null) {
                $updates[] = "observaciones = ?";
                $params[] = $observaciones;
                $types .= "s";
            }

            if ($vigencia !== null) {
                $updates[] = "vigencia = ?";
                $params[] = $vigencia;
                $types .= "s";
            }

            // Si se envían productos, recalcular
            if ($productos !== null && is_array($productos) && !empty($productos)) {
                // Eliminar detalles anteriores
                $deleteStmt = $conn->prepare("DELETE FROM cotizacion_detalles WHERE cotizacion_id = ?");
                $deleteStmt->bind_param("i", $id);
                $deleteStmt->execute();

                $subtotal = 0;
                $descuento = 0;
                $impuesto = 0;

                $detQuery = "INSERT INTO cotizacion_detalles (
                    cotizacion_id, producto_id, producto_nombre, cantidad,
                    precio_unitario, subtotal, impuesto, descuento, total, precio_tipo
                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
                $detStmt = $conn->prepare($detQuery);

                foreach ($productos as $prod) {
                    $producto_id = intval($prod['producto_id']);
                    $producto_nombre = trim($prod['producto_nombre']);
                    $cantidad = floatval($prod['cantidad']);
                    $precio_unitario = floatval($prod['precio_unitario']);
                    $desc_prod = floatval($prod['descuento'] ?? 0);
                    $imp_prod = floatval($prod['impuesto'] ?? 0);
                    $precio_tipo = trim($prod['precio_tipo'] ?? 'precio1');

                    $subtotal_prod = $cantidad * $precio_unitario;
                    $total_prod = $subtotal_prod - $desc_prod + $imp_prod;

                    $subtotal += $subtotal_prod;
                    $descuento += $desc_prod;
                    $impuesto += $imp_prod;

                    $detStmt->bind_param(
                        "iisdddddds",
                        $id, $producto_id, $producto_nombre, $cantidad,
                        $precio_unitario, $subtotal_prod, $imp_prod, $desc_prod, $total_prod, $precio_tipo
                    );
                    if (!$detStmt->execute()) {
                        $conn->rollback();
                        sendResponse(false, "Error al actualizar detalles");
                    }
                }

                $total = $subtotal - $descuento + $impuesto;

                $updates[] = "subtotal = ?";
                $params[] = $subtotal;
                $types .= "d";

                $updates[] = "impuesto = ?";
                $params[] = $impuesto;
                $types .= "d";

                $updates[] = "descuento = ?";
                $params[] = $descuento;
                $types .= "d";

                $updates[] = "total = ?";
                $params[] = $total;
                $types .= "d";
            }

            if (!empty($updates)) {
                $params[] = $id;
                $types .= "i";

                $query = "UPDATE cotizaciones SET " . implode(", ", $updates) . " WHERE id = ?";
                $stmt = $conn->prepare($query);
                $stmt->bind_param($types, ...$params);
                $stmt->execute();
            }

            $conn->commit();
            sendResponse(true, "Cotización actualizada exitosamente");

        } catch (Exception $e) {
            $conn->rollback();
            sendResponse(false, "Error al actualizar cotización: " . $e->getMessage());
        }
        break;

    case 'eliminarCotizacion':
        $id = intval($datapost['id'] ?? 0);

        if ($id <= 0) {
            sendResponse(false, "ID de cotización requerido");
        }

        try {
            $stmt = $conn->prepare("UPDATE cotizaciones SET activo = 0 WHERE id = ? AND activo = 1");
            $stmt->bind_param("i", $id);

            if ($stmt->execute() && $stmt->affected_rows > 0) {
                sendResponse(true, "Cotización eliminada exitosamente");
            } else {
                sendResponse(false, "Cotización no encontrada");
            }

        } catch (Exception $e) {
            sendResponse(false, "Error al eliminar cotización: " . $e->getMessage());
        }
        break;

    case 'convertirCotizacion':
        $id = intval($datapost['id'] ?? 0);
        $metodo_pago = isset($datapost['metodo_pago']) ? $datapost['metodo_pago'] : null;
        $tipo_entrega = $datapost['tipo_entrega'] ?? 'domicilio';
        $direccion_entrega = trim($datapost['direccion_entrega'] ?? '');

        if ($id <= 0) {
            sendResponse(false, "ID de cotización requerido");
        }

        try {
            // Obtener cotización
            $cotStmt = $conn->prepare("SELECT * FROM cotizaciones WHERE id = ? AND activo = 1");
            $cotStmt->bind_param("i", $id);
            $cotStmt->execute();
            $cotResult = $cotStmt->get_result();

            if ($cotResult->num_rows === 0) {
                sendResponse(false, "Cotización no encontrada");
            }

            $cot = $cotResult->fetch_assoc();

            if ($cot['estado'] === 'convertida') {
                sendResponse(false, "La cotización ya fue convertida a pedido");
            }

            // Obtener detalles de la cotización
            $detStmt = $conn->prepare("SELECT * FROM cotizacion_detalles WHERE cotizacion_id = ?");
            $detStmt->bind_param("i", $id);
            $detStmt->execute();
            $detResult = $detStmt->get_result();

            $detalles = [];
            while ($det = $detResult->fetch_assoc()) {
                $detalles[] = $det;
            }

            if (empty($detalles)) {
                sendResponse(false, "La cotización no tiene productos");
            }

            $conn->begin_transaction();

            // Generar folio de venta
            $folio = 'VTA-' . date('Ymd') . '-' . str_pad(rand(1, 9999), 4, '0', STR_PAD_LEFT);
            $checkStmt = $conn->prepare("SELECT id FROM ventas WHERE folio = ?");
            $checkStmt->bind_param("s", $folio);
            $checkStmt->execute();
            while ($checkStmt->get_result()->num_rows > 0) {
                $folio = 'VTA-' . date('Ymd') . '-' . str_pad(rand(1, 9999), 4, '0', STR_PAD_LEFT);
                $checkStmt->bind_param("s", $folio);
                $checkStmt->execute();
            }

            $estatus_pago = 'pendiente';
            $saldo_pendiente = ($metodo_pago === 'credito') ? floatval($cot['total']) : null;

            // Crear venta
            $insertVenta = "INSERT INTO ventas (
                folio, cliente_id, cliente_nombre, usuario_id, usuario_nombre,
                subtotal, impuesto, descuento, total, metodo_pago, estatus_pago, saldo_pendiente,
                tipo_entrega, direccion_entrega, estado, observaciones
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '', ?)";

            $ventaStmt = $conn->prepare($insertVenta);
            $ventaStmt->bind_param(
                "sisisddddssdss",
                $folio,
                $cot['cliente_id'],
                $cot['cliente_nombre'],
                $user['id'],
                $user['nombre'],
                $cot['subtotal'],
                $cot['impuesto'],
                $cot['descuento'],
                $cot['total'],
                $metodo_pago,
                $estatus_pago,
                $saldo_pendiente,
                $tipo_entrega,
                $direccion_entrega,
                $cot['observaciones']
            );

            if (!$ventaStmt->execute()) {
                $conn->rollback();
                sendResponse(false, "Error al crear venta desde cotización");
            }

            $venta_id = $conn->insert_id;

            // Insertar detalles de venta
            $detVentaQuery = "INSERT INTO venta_detalles (
                venta_id, producto_id, producto_nombre, cantidad,
                precio_unitario, subtotal, impuesto, descuento, total, precio_tipo
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

            $detVentaStmt = $conn->prepare($detVentaQuery);

            foreach ($detalles as $det) {
                $detVentaStmt->bind_param(
                    "iisdddddds",
                    $venta_id,
                    $det['producto_id'],
                    $det['producto_nombre'],
                    $det['cantidad'],
                    $det['precio_unitario'],
                    $det['subtotal'],
                    $det['impuesto'],
                    $det['descuento'],
                    $det['total'],
                    $det['precio_tipo']
                );

                if (!$detVentaStmt->execute()) {
                    $conn->rollback();
                    sendResponse(false, "Error al copiar detalles de cotización");
                }

                // Descontar stock
                $cantidad = floatval($det['cantidad']);
                $producto_id = intval($det['producto_id']);
                $stockStmt = $conn->prepare("UPDATE productos SET stock = stock - ? WHERE id = ?");
                $stockStmt->bind_param("di", $cantidad, $producto_id);
                $stockStmt->execute();
            }

            // Marcar cotización como convertida
            $updateCotStmt = $conn->prepare("UPDATE cotizaciones SET estado = 'convertida' WHERE id = ?");
            $updateCotStmt->bind_param("i", $id);
            $updateCotStmt->execute();

            // Actualizar crédito si aplica
            if ($metodo_pago === 'credito' && $cot['cliente_id']) {
                $totalCot = floatval($cot['total']);
                $creditoStmt = $conn->prepare("UPDATE clientes SET saldo_credito_usado = saldo_credito_usado + ? WHERE id = ?");
                $creditoStmt->bind_param("di", $totalCot, $cot['cliente_id']);
                $creditoStmt->execute();
            }

            $conn->commit();

            sendResponse(true, "Cotización convertida a pedido exitosamente", [
                'cotizacion_id' => $id,
                'venta_id' => $venta_id,
                'folio' => $folio
            ]);

        } catch (Exception $e) {
            $conn->rollback();
            sendResponse(false, "Error al convertir cotización: " . $e->getMessage());
        }
        break;

    case 'compartirCotizacion':
        $id = intval($datapost['id'] ?? 0);
        $formato = trim($datapost['formato'] ?? 'texto'); // texto o pdf

        if ($id <= 0) {
            sendResponse(false, "ID de cotización requerido");
        }

        try {
            // Obtener cotización con detalles
            $cotStmt = $conn->prepare("SELECT * FROM cotizaciones WHERE id = ? AND activo = 1");
            $cotStmt->bind_param("i", $id);
            $cotStmt->execute();
            $cotResult = $cotStmt->get_result();

            if ($cotResult->num_rows === 0) {
                sendResponse(false, "Cotización no encontrada");
            }

            $cot = $cotResult->fetch_assoc();

            $detStmt = $conn->prepare("SELECT producto_nombre, cantidad, precio_unitario, total FROM cotizacion_detalles WHERE cotizacion_id = ? ORDER BY id ASC");
            $detStmt->bind_param("i", $id);
            $detStmt->execute();
            $detResult = $detStmt->get_result();

            // Generar texto para WhatsApp
            $texto = "*COTIZACIÓN " . $cot['folio'] . "*\n";
            $texto .= "Cliente: " . $cot['cliente_nombre'] . "\n";
            $texto .= "Fecha: " . date('d/m/Y', strtotime($cot['fecha_creacion'])) . "\n";
            $texto .= "Vigencia: " . date('d/m/Y', strtotime($cot['vigencia'])) . "\n";
            $texto .= "---\n";

            $i = 1;
            while ($det = $detResult->fetch_assoc()) {
                $texto .= $i . ". " . $det['producto_nombre'] . "\n";
                $texto .= "   Cant: " . floatval($det['cantidad']) . " x \$" . number_format(floatval($det['precio_unitario']), 2) . " = \$" . number_format(floatval($det['total']), 2) . "\n";
                $i++;
            }

            $texto .= "---\n";
            if (floatval($cot['descuento']) > 0) {
                $texto .= "Descuento: -\$" . number_format(floatval($cot['descuento']), 2) . "\n";
            }
            $texto .= "*TOTAL: \$" . number_format(floatval($cot['total']), 2) . "*\n";

            if (!empty($cot['observaciones'])) {
                $texto .= "\nNotas: " . $cot['observaciones'] . "\n";
            }

            sendResponse(true, "Cotización lista para compartir", [
                'folio' => $cot['folio'],
                'texto' => $texto,
                'formato' => $formato
            ]);

        } catch (Exception $e) {
            sendResponse(false, "Error al compartir cotización: " . $e->getMessage());
        }
        break;

    default:
        sendResponse(false, "Operación no válida para cotizaciones");
        break;
}
