<?php
// FILE: /digitalpremium/actions/perfiles_vendidos_controlador.php
// Controlador con reglas de rol:
// - ventas: crear/editar/renovar/cancelar (NO eliminar)
// - cortes: SOLO eliminar (NO crear/editar/renovar/cancelar)
// - admin/superadmin: todo permitido

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

if (session_status() === PHP_SESSION_NONE) { session_start(); }
if (!isset($_SESSION['id_usuario'])) {
    header("Location: /digitalpremium/login.php?error=" . urlencode("Acceso no autorizado. Por favor, inicia sesión."));
    exit();
}

require_once '../config/db.php';
require_once '../includes/message_helper.php'; // add_message, generarMensajeParaCliente, limpiarNumeroWhatsApp, etc.
require_once '../includes/audit_helper.php'; // Auditoría de acciones
require_once '../includes/tenant_helper.php'; // para get_data_owner_id

$id_usuario_sesion  = (int)$_SESSION['id_usuario'];
$rol_usuario_sesion = strtolower((string)($_SESSION['rol'] ?? 'ventas')); // por defecto tratamos como ventas
$OWNER_ID = get_data_owner_id($pdo); // Para multi-tenancy

$redirect_url = "/digitalpremium/pages/perfiles_vendidos.php";
$mensaje      = '';
$tipo_mensaje = 'danger';

// --- Helpers ---
function getUserFilterClause(string $alias, string $rol_usuario_sesion): string {
    // superadmin, admin, ventas y cortes pueden ver todas las ventas
    // otros roles solo ven sus propias ventas
    return (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'ventas', 'cortes']))
        ? " AND {$alias}.id_usuario = :owner_id"
        : "";
}
function ajustarPerfilesDisponibles(PDO $pdo, int $id_cuenta_maestra, string $operacion, int $id_usuario_sesion, string $rol_usuario_sesion, int $cantidad = 1) {
    global $OWNER_ID;
    $sql_ver = "SELECT perfiles_disponibles, perfiles_total FROM cuentas_maestras WHERE id_cuenta_maestra = :id";
    $pv = [':id' => $id_cuenta_maestra];
    
    // Para Ventas y Cortes, permitir ajustar perfiles de cuentas maestras de otros usuarios
    if ($rol_usuario_sesion !== 'superadmin' && $rol_usuario_sesion !== 'admin' && $rol_usuario_sesion !== 'ventas' && $rol_usuario_sesion !== 'Ventas' && strtolower($rol_usuario_sesion) !== 'ventas' && $rol_usuario_sesion !== 'cortes') {
        $sql_ver .= " AND id_usuario = :owner";
        $pv[':owner'] = $OWNER_ID;
    }
    
    $st = $pdo->prepare($sql_ver);
    $st->execute($pv);
    $cm = $st->fetch(PDO::FETCH_ASSOC);
    if (!$cm) throw new Exception("La cuenta maestra no existe o no tienes permiso.");

    $sql = "";
    $p   = [':id' => $id_cuenta_maestra, ':cant' => $cantidad];
    if ($operacion === 'decrementar') {
        if ((int)$cm['perfiles_disponibles'] < $cantidad) {
            throw new Exception("No hay suficientes perfiles disponibles ({$cm['perfiles_disponibles']}).");
        }
        $sql = "UPDATE cuentas_maestras SET perfiles_disponibles = perfiles_disponibles - :cant WHERE id_cuenta_maestra = :id";
    } elseif ($operacion === 'incrementar') {
        $sql = "UPDATE cuentas_maestras SET perfiles_disponibles = LEAST(perfiles_total, perfiles_disponibles + :cant) WHERE id_cuenta_maestra = :id";
    } else {
        throw new Exception("Operación inválida: $operacion");
    }
    
    // Para Ventas y Cortes, permitir ajustar perfiles de cuentas maestras de otros usuarios
    if ($rol_usuario_sesion !== 'superadmin' && $rol_usuario_sesion !== 'admin' && $rol_usuario_sesion !== 'ventas' && $rol_usuario_sesion !== 'Ventas' && strtolower($rol_usuario_sesion) !== 'ventas' && $rol_usuario_sesion !== 'cortes') {
        $sql .= " AND id_usuario = :owner";
        $p[':owner'] = $OWNER_ID;
    }
    
    $u = $pdo->prepare($sql);
    if (!$u->execute($p)) {
        error_log("ajustarPerfilesDisponibles error: " . json_encode($u->errorInfo()));
        throw new Exception("No se pudo ajustar cupos.");
    }
}

// Función helper para obtener la fecha local del servidor
function getLocalDate(): string {
    // Usar la zona horaria configurada en PHP (America/Lima)
    return date('Y-m-d');
}

// Función helper para preservar filtros en la redirección
function preservarFiltrosEnRedireccion(): string {
    error_log("DEBUG preservarFiltrosEnRedireccion - FUNCIÓN EJECUTÁNDOSE - INICIO");
    
    global $filtros_para_preservar;
    
    error_log("DEBUG preservarFiltrosEnRedireccion - Variable global disponible: " . (isset($filtros_para_preservar) ? 'SÍ' : 'NO'));
    error_log("DEBUG preservarFiltrosEnRedireccion - Usando filtros capturados al inicio: " . json_encode($filtros_para_preservar));
    
    // Si hay filtros para preservar, retornar query string
    if (!empty($filtros_para_preservar)) {
        $query_string = "?" . http_build_query($filtros_para_preservar);
        error_log("DEBUG preservarFiltrosEnRedireccion - Query string generado: " . $query_string);
        return $query_string;
    }
    
    error_log("DEBUG preservarFiltrosEnRedireccion - No hay filtros para preservar");
    return "";
}

// --- Reglas por rol ---
function isAllowedAction(string $accion, string $rol): bool {
    $rol = strtolower($rol);
    
    if ($rol === 'superadmin' || $rol === 'admin') {
        return true;
    }

    // VENTAS
    $ventas_allow = [
        'agregar_perfil_vendido',
        'agregar_multiples_perfiles',
        'editar_perfil_vendido',
        'renovar',
        'renovar_desde_dashboard',
        'gestionar_eliminacion'
    ];
    // CORTES
    $cortes_allow = ['gestionar_eliminacion'];

    if ($rol === 'ventas') {
        return in_array($accion, $ventas_allow, true);
    }
    if ($rol === 'cortes') {
        return in_array($accion, $cortes_allow, true);
    }

    // por defecto tratamos como ventas
    return in_array($accion, $ventas_allow, true);
}

$accion              = $_POST['accion'] ?? $_GET['accion'] ?? null;
$created_profile_ids = [];
$isEditing           = false;

// CAPTURAR PARÁMETROS DE FILTROS AL INICIO para preservarlos después
error_log("DEBUG Controlador - INICIO DE EJECUCIÓN - Controlador cargado");
error_log("DEBUG Controlador - POST: " . json_encode($_POST));
error_log("DEBUG Controlador - GET: " . json_encode($_GET));

$filtros_para_preservar = [];
$parametros_filtro = [
    'buscar', 'filtro_estado', 'filtro_estado_cm', 'filtro_tipo_cuenta', 
    'filtro_vendedor', 'filtro_fecha_inicio', 'filtro_fecha_fin', 'filtro_precio_min', 
    'filtro_precio_max', 'ordenar_por', 'orden', 'cargar_mas'
];

// Excluir parámetros que NO son filtros
$parametros_excluir = [
    'accion', 'id_perfil_vendido', 'tipo_gestion', 'mensaje', 'tipo', 'debug'
];

foreach ($parametros_filtro as $param) {
    if (!in_array($param, $parametros_excluir)) {
        if (isset($_POST[$param]) && $_POST[$param] !== '') {
            $filtros_para_preservar[$param] = $_POST[$param];
            error_log("DEBUG Controlador - Filtro POST capturado: $param = " . $_POST[$param]);
        } elseif (isset($_GET[$param]) && $_GET[$param] !== '') {
            $filtros_para_preservar[$param] = $_GET[$param];
            error_log("DEBUG Controlador - Filtro GET capturado: $param = " . $_GET[$param]);
        }
    }
}

error_log("DEBUG Controlador - Filtros capturados al inicio: " . json_encode($filtros_para_preservar));

try {
    if (!$accion) throw new Exception("No se ha proporcionado ninguna acción.");

    // Chequeo de permisos por rol
    if (!isAllowedAction($accion, $rol_usuario_sesion)) {
        throw new Exception("No tienes permisos para realizar esta acción con tu rol actual.");
    }

    $pdo->beginTransaction();

    switch ($accion) {
        case 'agregar_perfil_vendido': {
            $isEditing = false;
            $required = ['id_cliente','id_cuenta_maestra','nombre_perfil_cliente','fecha_inicio_servicio','duracion_dias','precio_venta','estado_suscripcion'];
            foreach ($required as $f) {
                if (!isset($_POST[$f]) || (is_string($_POST[$f]) && trim($_POST[$f]) === '')) {
                    throw new Exception("El campo '{$f}' es obligatorio.");
                }
            }
            $id_cliente        = filter_var($_POST['id_cliente'], FILTER_VALIDATE_INT);
            $id_cuenta_maestra = filter_var($_POST['id_cuenta_maestra'], FILTER_VALIDATE_INT);
            if ($id_cliente === false || $id_cuenta_maestra === false) throw new Exception("Cliente o cuenta maestra inválidos.");

            // Para Ventas, permitir usar clientes y cuentas maestras de otros usuarios
            if ($rol_usuario_sesion === 'ventas' || $rol_usuario_sesion === 'Ventas' || strtolower($rol_usuario_sesion) === 'ventas') {
                // Verificar que el cliente existe (sin restricción de propiedad)
                $sqlC = "SELECT id_cliente FROM clientes c WHERE c.id_cliente = :idc";
                $pC = [':idc' => $id_cliente];
                $stC = $pdo->prepare($sqlC); $stC->execute($pC);
                if (!$stC->fetch()) throw new Exception("El cliente no existe.");

                // Verificar que la cuenta maestra existe (sin restricción de propiedad)
                $sqlM = "SELECT id_cuenta_maestra FROM cuentas_maestras cm WHERE cm.id_cuenta_maestra = :idcm";
                $pM = [':idcm' => $id_cuenta_maestra];
                $stM = $pdo->prepare($sqlM); $stM->execute($pM);
                if (!$stM->fetch()) throw new Exception("La cuenta maestra no existe.");
            } else {
                // Para otros roles, mantener la validación de propiedad
                $sqlC = "SELECT id_cliente FROM clientes c WHERE c.id_cliente = :idc" . getUserFilterClause('c', $rol_usuario_sesion);
                $pC = [':idc' => $id_cliente];
                if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'ventas', 'cortes'])) { $pC[':owner_id'] = $OWNER_ID; }
                $stC = $pdo->prepare($sqlC); $stC->execute($pC);
                if (!$stC->fetch()) throw new Exception("El cliente no te pertenece.");

                $sqlM = "SELECT id_cuenta_maestra FROM cuentas_maestras cm WHERE cm.id_cuenta_maestra = :idcm" . getUserFilterClause('cm', $rol_usuario_sesion);
                $pM = [':idcm' => $id_cuenta_maestra];
                if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'ventas', 'cortes'])) { $pM[':owner_id'] = $OWNER_ID; }
                $stM = $pdo->prepare($sqlM); $stM->execute($pM);
                if (!$stM->fetch()) throw new Exception("La cuenta maestra no te pertenece.");
            }

            $nombre_perfil_cliente = trim($_POST['nombre_perfil_cliente']);
            $pin_perfil_cliente    = (isset($_POST['pin_perfil_cliente']) && trim($_POST['pin_perfil_cliente']) !== '') ? trim($_POST['pin_perfil_cliente']) : null;
            $fecha_inicio          = $_POST['fecha_inicio_servicio'];
            $duracion              = filter_var($_POST['duracion_dias'], FILTER_VALIDATE_INT);
            $precio                = filter_var($_POST['precio_venta'], FILTER_VALIDATE_FLOAT);
            $estado_nuevo          = filter_var($_POST['estado_suscripcion'], FILTER_VALIDATE_INT);
            $notas                 = (isset($_POST['notas_suscripcion']) && trim($_POST['notas_suscripcion']) !== '') ? trim($_POST['notas_suscripcion']) : null;

            $dt_fin = new DateTime($fecha_inicio);
            $dt_fin->modify("+{$duracion} days");
            $fecha_fin = $dt_fin->format('Y-m-d');

            if ($estado_nuevo == 1) {
                ajustarPerfilesDisponibles($pdo, $id_cuenta_maestra, 'decrementar', $id_usuario_sesion, $rol_usuario_sesion);
            }

            $ins = $pdo->prepare("
                INSERT INTO perfiles_vendidos
                    (id_usuario, id_cliente, id_cuenta_maestra, nombre_perfil_cliente, pin_perfil_cliente, fecha_inicio_servicio, fecha_fin_servicio, precio_venta, estado_suscripcion, notas_suscripcion)
                VALUES
                    (:owner, :idc, :idcm, :nombre, :pin, :finicio, :ffin, :precio, :estado, :notas)
            ");
            $ok = $ins->execute([
                ':owner'  => $id_usuario_sesion,
                ':idc'    => $id_cliente,
                ':idcm'   => $id_cuenta_maestra,
                ':nombre' => $nombre_perfil_cliente,
                ':pin'    => $pin_perfil_cliente,
                ':finicio'=> $fecha_inicio,
                ':ffin'   => $fecha_fin,
                ':precio' => $precio,
                ':estado' => $estado_nuevo,
                ':notas'  => $notas
            ]);
            if (!$ok) { error_log("Insert error: " . json_encode($ins->errorInfo())); throw new Exception("No se pudo crear la suscripción."); }

            $new_profile_id = (int)$pdo->lastInsertId();
            $created_profile_ids[] = $new_profile_id;
            
            // Auditoría
            audit($pdo, $id_usuario_sesion, $rol_usuario_sesion, 'create', 'perfiles_vendidos', $new_profile_id, [
                'cliente_id' => $id_cliente,
                'cuenta_maestra_id' => $id_cuenta_maestra,
                'nombre_perfil' => $nombre_perfil_cliente,
                'precio' => $precio,
                'estado' => $estado_nuevo
            ]);
            
            $mensaje = "Suscripción creada exitosamente."; $tipo_mensaje = 'success';
            break;
        }

        case 'editar_perfil_vendido': {
            $isEditing = true;
            
            $required = ['id_cliente','id_cuenta_maestra','nombre_perfil_cliente','fecha_inicio_servicio','duracion_dias','precio_venta','estado_suscripcion','id_perfil_vendido'];
            foreach ($required as $f) {
                if (!isset($_POST[$f]) || (is_string($_POST[$f]) && trim($_POST[$f]) === '')) {
                    throw new Exception("El campo '{$f}' es obligatorio para editar.");
                }
            }
            $id_cliente        = filter_var($_POST['id_cliente'], FILTER_VALIDATE_INT);
            $id_cuenta_maestra = filter_var($_POST['id_cuenta_maestra'], FILTER_VALIDATE_INT);
            $id_perfil         = filter_var($_POST['id_perfil_vendido'], FILTER_VALIDATE_INT);
            if ($id_cliente === false || $id_cuenta_maestra === false || $id_perfil === false) throw new Exception("IDs inválidos.");

            // Para Ventas, permitir editar perfiles de otros usuarios (solo verificar que existan)
            if ($rol_usuario_sesion === 'ventas' || $rol_usuario_sesion === 'Ventas' || strtolower($rol_usuario_sesion) === 'ventas') {
                // Verificar que el cliente existe (sin restricción de propiedad)
                $sqlC = "SELECT id_cliente FROM clientes c WHERE c.id_cliente = :idc";
                $pC   = [':idc' => $id_cliente];
                $stC = $pdo->prepare($sqlC); $stC->execute($pC);
                $cliente_existe = $stC->fetch();
                if (!$cliente_existe) throw new Exception("El cliente no existe.");

                // Verificar que la cuenta maestra existe (sin restricción de propiedad)
                $sqlM = "SELECT id_cuenta_maestra FROM cuentas_maestras cm WHERE cm.id_cuenta_maestra = :idcm";
                $pM   = [':idcm' => $id_cuenta_maestra];
                $stM = $pdo->prepare($sqlM); $stM->execute($pM);
                $cm_existe = $stM->fetch();
                if (!$cm_existe) throw new Exception("La cuenta maestra no existe.");

                // Verificar que el perfil existe (sin restricción de propiedad)
                $sqlOld = "SELECT id_cuenta_maestra, estado_suscripcion FROM perfiles_vendidos pv WHERE pv.id_perfil_vendido = :idp";
                $pOld   = [':idp' => $id_perfil];
                $stOld = $pdo->prepare($sqlOld); $stOld->execute($pOld);
                $old = $stOld->fetch(PDO::FETCH_ASSOC);
                if (!$old) throw new Exception("La suscripción no existe.");
            } else {
                // Para otros roles, mantener la validación de propiedad
                $sqlC = "SELECT id_cliente FROM clientes c WHERE c.id_cliente = :idc" . getUserFilterClause('c', $rol_usuario_sesion);
                $pC   = [':idc' => $id_cliente];
                if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'ventas', 'cortes'])) { $pC[':owner_id'] = $OWNER_ID; }
                $stC = $pdo->prepare($sqlC); $stC->execute($pC);
                if (!$stC->fetch()) throw new Exception("El cliente no te pertenece.");

                $sqlM = "SELECT id_cuenta_maestra FROM cuentas_maestras cm WHERE cm.id_cuenta_maestra = :idcm" . getUserFilterClause('cm', $rol_usuario_sesion);
                $pM   = [':idcm' => $id_cuenta_maestra];
                if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'ventas', 'cortes'])) { $pM[':owner_id'] = $OWNER_ID; }
                $stM = $pdo->prepare($sqlM); $stM->execute($pM);
                if (!$stM->fetch()) throw new Exception("La cuenta maestra no te pertenece.");

                $sqlOld = "SELECT id_cuenta_maestra, estado_suscripcion FROM perfiles_vendidos pv WHERE pv.id_perfil_vendido = :idp" . getUserFilterClause('pv', $rol_usuario_sesion);
                $pOld   = [':idp' => $id_perfil];
                if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'ventas', 'cortes'])) { $pOld[':owner_id'] = $OWNER_ID; }
                $stOld = $pdo->prepare($sqlOld); $stOld->execute($pOld);
                $old = $stOld->fetch(PDO::FETCH_ASSOC);
                if (!$old) throw new Exception("La suscripción no existe o no tienes permiso.");
            }

            $old_estado = (int)$old['estado_suscripcion'];
            $old_cm     = (int)$old['id_cuenta_maestra'];

            $nombre_perfil_cliente = trim($_POST['nombre_perfil_cliente']);
            $pin_perfil_cliente    = (isset($_POST['pin_perfil_cliente']) && trim($_POST['pin_perfil_cliente']) !== '') ? trim($_POST['pin_perfil_cliente']) : null;
            $fecha_inicio          = $_POST['fecha_inicio_servicio'];
            $duracion              = filter_var($_POST['duracion_dias'], FILTER_VALIDATE_INT);
            $precio                = filter_var($_POST['precio_venta'], FILTER_VALIDATE_FLOAT);
            $estado_nuevo          = filter_var($_POST['estado_suscripcion'], FILTER_VALIDATE_INT);
            $notas                 = (isset($_POST['notas_suscripcion']) && trim($_POST['notas_suscripcion']) !== '') ? trim($_POST['notas_suscripcion']) : null;

            $dt_fin = new DateTime($fecha_inicio);
            $dt_fin->modify("+{$duracion} days");
            $fecha_fin = $dt_fin->format('Y-m-d');

            if ($id_cuenta_maestra !== $old_cm) {
                if ($old_estado == 1) ajustarPerfilesDisponibles($pdo, $old_cm, 'incrementar', $id_usuario_sesion, $rol_usuario_sesion);
                if ($estado_nuevo == 1) ajustarPerfilesDisponibles($pdo, $id_cuenta_maestra, 'decrementar', $id_usuario_sesion, $rol_usuario_sesion);
            } else {
                if ($estado_nuevo != $old_estado) {
                    if ($estado_nuevo == 1 && $old_estado != 1) ajustarPerfilesDisponibles($pdo, $id_cuenta_maestra, 'decrementar', $id_usuario_sesion, $rol_usuario_sesion);
                    elseif ($estado_nuevo != 1 && $old_estado == 1) ajustarPerfilesDisponibles($pdo, $id_cuenta_maestra, 'incrementar', $id_usuario_sesion, $rol_usuario_sesion);
                }
            }

            $sqlU = "UPDATE perfiles_vendidos pv SET
                        id_cliente = :idc,
                        id_cuenta_maestra = :idcm,
                        nombre_perfil_cliente = :nombre,
                        pin_perfil_cliente = :pin,
                        fecha_inicio_servicio = :finicio,
                        fecha_fin_servicio = :ffin,
                        precio_venta = :precio,
                        estado_suscripcion = :estado,
                        notas_suscripcion = :notas,
                        fecha_actualizacion = CURRENT_TIMESTAMP
                     WHERE pv.id_perfil_vendido = :idp";
            $pU = [
                ':idc'    => $id_cliente,
                ':idcm'   => $id_cuenta_maestra,
                ':nombre' => $nombre_perfil_cliente,
                ':pin'    => $pin_perfil_cliente,
                ':finicio'=> $fecha_inicio,
                ':ffin'   => $fecha_fin,
                ':precio' => $precio,
                ':estado' => $estado_nuevo,
                ':notas'  => $notas,
                ':idp'    => $id_perfil
            ];
            // Para Ventas y Cortes, permitir editar perfiles de otros usuarios
            if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'ventas', 'cortes'])) {
                $sqlU .= " AND pv.id_usuario = :owner";
                $pU[':owner'] = $id_usuario_sesion;
            }
            
            $u = $pdo->prepare($sqlU);
            if (!$u->execute($pU)) { 
                error_log("Update error: " . json_encode($u->errorInfo())); 
                throw new Exception("No se pudo actualizar la suscripción."); 
            }

            // Auditoría
            audit($pdo, $id_usuario_sesion, $rol_usuario_sesion, 'update', 'perfiles_vendidos', $id_perfil, [
                'cliente_id' => $id_cliente,
                'cuenta_maestra_id' => $id_cuenta_maestra,
                'nombre_perfil' => $nombre_perfil_cliente,
                'precio' => $precio,
                'estado_anterior' => $old_estado,
                'estado_nuevo' => $estado_nuevo
            ]);

            $mensaje = "Suscripción actualizada exitosamente."; $tipo_mensaje = 'success';
            break;
        }

        case 'agregar_multiples_perfiles': {
            $id_cliente = filter_var($_POST['id_cliente'] ?? null, FILTER_VALIDATE_INT);
            $perfiles_json = $_POST['perfiles_json'] ?? '';
            if ($id_cliente === false || trim($perfiles_json) === '') throw new Exception("Datos incompletos para creación múltiple.");
            $perfiles_data = json_decode($perfiles_json, true);
            if (empty($perfiles_data) || !is_array($perfiles_data)) throw new Exception("Formato inválido de perfiles.");

            // Para Ventas, permitir usar clientes de otros usuarios
            if ($rol_usuario_sesion === 'ventas' || $rol_usuario_sesion === 'Ventas' || strtolower($rol_usuario_sesion) === 'ventas') {
                $sqlC = "SELECT id_cliente FROM clientes c WHERE c.id_cliente = :idc";
                $pC   = [':idc' => $id_cliente];
                $stC = $pdo->prepare($sqlC); $stC->execute($pC);
                if (!$stC->fetch()) throw new Exception("El cliente no existe.");
            } else {
                $sqlC = "SELECT id_cliente FROM clientes c WHERE c.id_cliente = :idc" . getUserFilterClause('c', $rol_usuario_sesion);
                $pC   = [':idc' => $id_cliente];
                if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'ventas', 'cortes'])) { $pC[':owner_id'] = $OWNER_ID; }
                $stC = $pdo->prepare($sqlC); $stC->execute($pC);
                if (!$stC->fetch()) throw new Exception("El cliente no te pertenece.");
            }

            $ins = $pdo->prepare("
                INSERT INTO perfiles_vendidos
                    (id_usuario, id_cliente, id_cuenta_maestra, nombre_perfil_cliente, pin_perfil_cliente, fecha_inicio_servicio, fecha_fin_servicio, precio_venta, estado_suscripcion, notas_suscripcion)
                VALUES
                    (:owner, :idc, :idcm, :nombre, :pin, :finicio, :ffin, :precio, :estado, :notas)
            ");
            $cuentas_afectadas = [];

            foreach ($perfiles_data as $i => $pf) {
                $req = ['id_cuenta_maestra','nombre_perfil_cliente','fecha_inicio_servicio','duracion_dias','fecha_fin_servicio','precio_venta','estado_suscripcion'];
                foreach ($req as $f) {
                    if (!isset($pf[$f]) || (is_string($pf[$f]) && trim($pf[$f]) === '')) {
                        throw new Exception("Perfil #".($i+1).": falta '{$f}'.");
                    }
                }
                $idcm  = filter_var($pf['id_cuenta_maestra'], FILTER_VALIDATE_INT);
                if ($idcm === false) throw new Exception("Perfil #".($i+1).": cuenta maestra inválida.");

                // Para Ventas, permitir usar cuentas maestras de otros usuarios
                if ($rol_usuario_sesion === 'ventas' || $rol_usuario_sesion === 'Ventas' || strtolower($rol_usuario_sesion) === 'ventas') {
                    $sqlM = "SELECT id_cuenta_maestra FROM cuentas_maestras cm WHERE cm.id_cuenta_maestra = :idcm";
                    $pM   = [':idcm' => $idcm];
                    $stM  = $pdo->prepare($sqlM); $stM->execute($pM);
                    if (!$stM->fetch()) throw new Exception("Perfil #".($i+1).": La cuenta maestra no existe.");
                } else {
                    $sqlM = "SELECT id_cuenta_maestra FROM cuentas_maestras cm WHERE cm.id_cuenta_maestra = :idcm" . getUserFilterClause('cm', $rol_usuario_sesion);
                    $pM   = [':idcm' => $idcm];
                    if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'ventas', 'cortes'])) { $pM[':owner_id'] = $OWNER_ID; }
                    $stM  = $pdo->prepare($sqlM); $stM->execute($pM);
                    if (!$stM->fetch()) throw new Exception("Perfil #".($i+1).": La cuenta maestra no te pertenece.");
                }

                $nombre = trim($pf['nombre_perfil_cliente']);
                $pin    = (isset($pf['pin_perfil_cliente']) && trim($pf['pin_perfil_cliente']) !== '') ? trim($pf['pin_perfil_cliente']) : null;
                $finicio= $pf['fecha_inicio_servicio'];
                $ffin   = $pf['fecha_fin_servicio']; // precalculado en front
                $precio = filter_var($pf['precio_venta'], FILTER_VALIDATE_FLOAT);
                $estado = filter_var($pf['estado_suscripcion'], FILTER_VALIDATE_INT);
                $notas  = (isset($pf['notas_suscripcion']) && trim($pf['notas_suscripcion']) !== '') ? trim($pf['notas_suscripcion']) : (isset($_POST['notas_suscripcion_general']) ? trim($_POST['notas_suscripcion_general']) : null);

                $ok = $ins->execute([
                    ':owner'  => $id_usuario_sesion,
                    ':idc'    => $id_cliente,
                    ':idcm'   => $idcm,
                    ':nombre' => $nombre,
                    ':pin'    => $pin,
                    ':finicio'=> $finicio,
                    ':ffin'   => $ffin,
                    ':precio' => $precio,
                    ':estado' => $estado,
                    ':notas'  => ($notas !== '' ? $notas : null)
                ]);
                if (!$ok) { error_log("Insert multiple #$i error: " . json_encode($ins->errorInfo())); throw new Exception("Error al crear el perfil #".($i+1)); }
                $created_profile_ids[] = (int)$pdo->lastInsertId();
                if ($estado == 1) { $cuentas_afectadas[$idcm] = ($cuentas_afectadas[$idcm] ?? 0) + 1; }
            }
            foreach ($cuentas_afectadas as $cm_id => $cant) {
                ajustarPerfilesDisponibles($pdo, $cm_id, 'decrementar', $id_usuario_sesion, $rol_usuario_sesion, $cant);
            }
            
            // Auditoría para múltiples perfiles
            foreach ($created_profile_ids as $profile_id) {
                audit($pdo, $id_usuario_sesion, $rol_usuario_sesion, 'create', 'perfiles_vendidos', $profile_id, [
                    'cliente_id' => $id_cliente,
                    'creacion_multiple' => true,
                    'total_creados' => count($created_profile_ids)
                ]);
            }
            
            $mensaje = "Se han creado " . count($created_profile_ids) . " suscripciones exitosamente."; $tipo_mensaje = 'success';
            break;
        }

        case 'renovar_desde_dashboard': {
            $id_perfil = filter_var($_POST['id_perfil_vendido'] ?? null, FILTER_VALIDATE_INT);
            $nueva_fin = $_POST['fecha_fin_servicio'] ?? null;
            $nuevo_prec= $_POST['precio_venta'] ?? null;
            $redirect_url = "/digitalpremium/pages/dashboard2.php";
            if (!$id_perfil || !$nueva_fin) { add_message("Error: faltan datos.", "danger"); throw new Exception("Datos incompletos."); }

            // Para Ventas, permitir renovar perfiles de otros usuarios (solo verificar que existan)
            if ($rol_usuario_sesion === 'ventas' || $rol_usuario_sesion === 'Ventas' || strtolower($rol_usuario_sesion) === 'ventas') {
                // Consulta sin restricciones de propiedad para Ventas
                $sqlF = "SELECT 
                            pv.id_cuenta_maestra, 
                            pv.estado_suscripcion, 
                            pv.precio_venta,
                            c.nombre_completo AS nombre_cliente,
                            p.nombre_plataforma,
                            pv.nombre_perfil_cliente
                         FROM perfiles_vendidos pv 
                         JOIN clientes c ON pv.id_cliente = c.id_cliente 
                         JOIN cuentas_maestras cm ON pv.id_cuenta_maestra = cm.id_cuenta_maestra
                         JOIN plataformas p ON cm.id_plataforma = p.id_plataforma
                         WHERE pv.id_perfil_vendido = :idp";
                
                $pF   = [':idp' => $id_perfil];
                $stF = $pdo->prepare($sqlF); $stF->execute($pF);
                $cur = $stF->fetch(PDO::FETCH_ASSOC);
                if (!$cur) { add_message("Perfil no encontrado.", "danger"); throw new Exception("Perfil no encontrado."); }
            } else {
                // Para otros roles, mantener la validación de propiedad
                $sqlF = "SELECT 
                            pv.id_cuenta_maestra, 
                            pv.estado_suscripcion, 
                            pv.precio_venta,
                            c.nombre_completo AS nombre_cliente,
                            p.nombre_plataforma,
                            pv.nombre_perfil_cliente
                         FROM perfiles_vendidos pv 
                         JOIN clientes c ON pv.id_cliente = c.id_cliente 
                         JOIN cuentas_maestras cm ON pv.id_cuenta_maestra = cm.id_cuenta_maestra
                         JOIN plataformas p ON cm.id_plataforma = p.id_plataforma
                         WHERE pv.id_perfil_vendido = :idp" . getUserFilterClause('pv', $rol_usuario_sesion);
                
                $pF   = [':idp' => $id_perfil];
                if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'ventas', 'cortes'])) { $pF[':owner_id'] = $OWNER_ID; }
                $stF = $pdo->prepare($sqlF); $stF->execute($pF);
                $cur = $stF->fetch(PDO::FETCH_ASSOC);
                if (!$cur) { add_message("Perfil no encontrado o sin permisos.", "danger"); throw new Exception("Perfil no encontrado."); }
            }

            $old_estado = (int)$cur['estado_suscripcion'];
            $cm_id      = (int)$cur['id_cuenta_maestra'];
            $old_prec   = (float)$cur['precio_venta'];
            $precio_upd = ($nuevo_prec !== null && $nuevo_prec !== '') ? (float)$nuevo_prec : $old_prec;

            $sqlU = "UPDATE perfiles_vendidos pv SET
                        fecha_inicio_servicio = :fecha_inicio,
                        fecha_fin_servicio = :ffin,
                        precio_venta = :precio,
                        estado_suscripcion = 1,
                        fecha_ultima_renovacion = :fecha_renovacion,
                        fecha_actualizacion = CURRENT_TIMESTAMP
                     WHERE pv.id_perfil_vendido = :idp";
            $pU = [':fecha_inicio' => getLocalDate(), ':ffin' => $nueva_fin, ':precio' => $precio_upd, ':idp' => $id_perfil, ':fecha_renovacion' => getLocalDate()];
            
            // Para Ventas y Cortes, permitir renovar perfiles de otros usuarios
            if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'ventas', 'cortes'])) { 
                $sqlU .= " AND pv.id_usuario = :owner"; 
                $pU[':owner'] = $id_usuario_sesion; 
            }
            $u = $pdo->prepare($sqlU);
            if ($u->execute($pU)) {
                if ($u->rowCount() > 0 && $old_estado != 1) ajustarPerfilesDisponibles($pdo, $cm_id, 'decrementar', $id_usuario_sesion, $rol_usuario_sesion);
                
                // La renovación se registra automáticamente en la tabla perfiles_vendidos
                $mensaje = "Suscripción renovada exitosamente.";
                
                // Auditoría
                audit($pdo, $id_usuario_sesion, $rol_usuario_sesion, 'renovar', 'perfiles_vendidos', $id_perfil, [
                    'cuenta_maestra_id' => $cm_id,
                    'estado_anterior' => $old_estado,
                    'fecha_fin_nueva' => $nueva_fin,
                    'precio_anterior' => $old_prec,
                    'precio_nuevo' => $precio_upd
                ]);
                
                $tipo_mensaje = 'success';
            } else {
                error_log("Renovar dashboard error: " . json_encode($u->errorInfo()));
                throw new Exception("No se pudo renovar.");
            }
            break;
        }

        case 'renovar': {
            $id_perfil = filter_var($_POST['id_perfil_vendido'] ?? $_GET['id_perfil_vendido'] ?? null, FILTER_VALIDATE_INT);
            if (!$id_perfil) throw new Exception("ID de perfil inválido.");

            // Para Ventas, permitir renovar perfiles de otros usuarios (solo verificar que existan)
            if ($rol_usuario_sesion === 'ventas' || $rol_usuario_sesion === 'Ventas' || strtolower($rol_usuario_sesion) === 'ventas') {
                // Consulta sin restricciones de propiedad para Ventas
                $sqlV = "SELECT 
                            pv.id_cuenta_maestra, 
                            pv.estado_suscripcion, 
                            pv.precio_venta,
                            c.nombre_completo AS nombre_cliente,
                            p.nombre_plataforma,
                            pv.nombre_perfil_cliente
                         FROM perfiles_vendidos pv 
                         JOIN clientes c ON pv.id_cliente = c.id_cliente 
                         JOIN cuentas_maestras cm ON pv.id_cuenta_maestra = cm.id_cuenta_maestra
                         JOIN plataformas p ON cm.id_plataforma = p.id_plataforma
                         WHERE pv.id_perfil_vendido = :idp";
                
                $pV   = [':idp' => $id_perfil];
                $stV = $pdo->prepare($sqlV); $stV->execute($pV);
                $info = $stV->fetch(PDO::FETCH_ASSOC);
                if (!$info) throw new Exception("Perfil no encontrado.");
            } else {
                // Para otros roles, mantener la validación de propiedad
                $sqlV = "SELECT 
                            pv.id_cuenta_maestra, 
                            pv.estado_suscripcion, 
                            pv.precio_venta,
                            c.nombre_completo AS nombre_cliente,
                            p.nombre_plataforma,
                            pv.nombre_perfil_cliente
                         FROM perfiles_vendidos pv 
                         JOIN clientes c ON pv.id_cliente = c.id_cliente 
                         JOIN cuentas_maestras cm ON pv.id_cuenta_maestra = cm.id_cuenta_maestra
                         JOIN plataformas p ON cm.id_plataforma = p.id_plataforma
                         WHERE pv.id_perfil_vendido = :idp" . getUserFilterClause('pv', $rol_usuario_sesion);
                
                $pV   = [':idp' => $id_perfil];
                if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'ventas', 'cortes'])) { $pV[':owner_id'] = $OWNER_ID; }
                $stV = $pdo->prepare($sqlV); $stV->execute($pV);
                $info = $stV->fetch(PDO::FETCH_ASSOC);
                if (!$info) throw new Exception("Perfil no encontrado o sin permiso.");
            }

            $cm_id      = (int)$info['id_cuenta_maestra'];
            $estado_old = (int)$info['estado_suscripcion'];
            $precio_old = (float)$info['precio_venta'];

            $nueva_fin  = $_POST['fecha_fin_servicio'] ?? null;
            $precio_new = filter_var($_POST['precio_venta'] ?? null, FILTER_VALIDATE_FLOAT, FILTER_NULL_ON_FAILURE);
            if (!$nueva_fin) throw new Exception("La nueva fecha es obligatoria.");

            // Si no se especifica precio, usar el actual
            if ($precio_new === null || $precio_new === '') {
                $precio_new = $precio_old;
            }

            if ($estado_old != 1) ajustarPerfilesDisponibles($pdo, $cm_id, 'decrementar', $id_usuario_sesion, $rol_usuario_sesion);

            $sqlU = "UPDATE perfiles_vendidos pv SET
                        fecha_inicio_servicio = :fecha_inicio,
                        fecha_fin_servicio = :ffin,
                        precio_venta = :precio,
                        estado_suscripcion = 1,
                        fecha_ultima_renovacion = :fecha_renovacion,
                        fecha_actualizacion = CURRENT_TIMESTAMP
                     WHERE pv.id_perfil_vendido = :idp";
            $pU = [':fecha_inicio' => getLocalDate(), ':ffin' => $nueva_fin, ':precio' => $precio_new, ':idp' => $id_perfil, ':fecha_renovacion' => getLocalDate()];
            
            // Para Ventas y Cortes, permitir renovar perfiles de otros usuarios
            if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'ventas', 'cortes'])) { 
                $sqlU .= " AND pv.id_usuario = :owner"; 
                $pU[':owner'] = $id_usuario_sesion; 
            }
            $u = $pdo->prepare($sqlU);
            if (!$u->execute($pU)) { error_log("Renovar error: " . json_encode($u->errorInfo())); throw new Exception("No se pudo renovar."); }

            // La renovación se registra automáticamente en la tabla perfiles_vendidos
            $mensaje = "Suscripción renovada exitosamente.";

            // Auditoría de la renovación
            audit($pdo, $id_usuario_sesion, $rol_usuario_sesion, 'renovar', 'perfiles_vendidos', $id_perfil, [
                'cuenta_maestra_id' => $cm_id,
                'estado_anterior' => $estado_old,
                'fecha_fin_nueva' => $nueva_fin,
                'precio_anterior' => $precio_old,
                'precio_nuevo' => $precio_new
            ]);

            $tipo_mensaje = 'success';
            break;
        }

        case 'gestionar_eliminacion': {
            $id_perfil = filter_var($_POST['id_perfil_vendido'] ?? null, FILTER_VALIDATE_INT);
            $tipo_gestion = $_POST['tipo_gestion'] ?? 'cancelar'; // Por defecto, la opción más segura

            if (!$id_perfil) {
                throw new Exception("ID de perfil inválido.");
            }

            // Comprobación de permisos granular dentro de la acción
            if ($tipo_gestion === 'cancelar' && !in_array($rol_usuario_sesion, ['superadmin', 'admin', 'cortes'])) {
                throw new Exception("No tienes permiso para cancelar suscripciones.");
            }
            if ($tipo_gestion === 'eliminar_con_reembolso' && !in_array($rol_usuario_sesion, ['superadmin', 'admin', 'cortes'])) {
                throw new Exception("No tienes permiso para eliminar suscripciones permanentemente.");
            }

            // Obtener el estado actual de la suscripción para ajustar los perfiles disponibles
            $sqlV = "SELECT id_cuenta_maestra, estado_suscripcion FROM perfiles_vendidos pv WHERE pv.id_perfil_vendido = :idp";
            $pV   = [':idp' => $id_perfil];
            
            // Para cortes, permitir ver perfiles de cualquier usuario (como admin)
            if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'cortes'])) { 
                $sqlV .= getUserFilterClause('pv', $rol_usuario_sesion);
                $pV[':owner_id'] = $OWNER_ID; 
            }
            $stV = $pdo->prepare($sqlV); $stV->execute($pV);
            $info = $stV->fetch(PDO::FETCH_ASSOC);

            if (!$info) {
                throw new Exception("Perfil no encontrado o sin permiso.");
            }

            $cm_id      = (int)$info['id_cuenta_maestra'];
            $estado_old = (int)$info['estado_suscripcion'];

            if ($tipo_gestion === 'cancelar') {
                // Opción 1: Cancelar la suscripción (marcar como estado 2)
                if ($estado_old == 1) {
                    ajustarPerfilesDisponibles($pdo, $cm_id, 'incrementar', $id_usuario_sesion, $rol_usuario_sesion);
                }

                $sqlU = "UPDATE perfiles_vendidos pv SET estado_suscripcion = 2, fecha_actualizacion = CURRENT_TIMESTAMP WHERE pv.id_perfil_vendido = :idp";
                $pU = [':idp' => $id_perfil];
                
                if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'cortes'])) { 
                    $sqlU .= " AND pv.id_usuario = :owner"; 
                    $pU[':owner'] = $id_usuario_sesion; 
                }
                
                $u = $pdo->prepare($sqlU);
                if (!$u->execute($pU)) { 
                    error_log("Cancelar (gestionar) error: " . json_encode($u->errorInfo())); 
                    throw new Exception("No se pudo cancelar la suscripción."); 
                }

                // Auditoría
                audit($pdo, $id_usuario_sesion, $rol_usuario_sesion, 'cancelar', 'perfiles_vendidos', $id_perfil, [
                    'cuenta_maestra_id' => $cm_id,
                    'estado_anterior' => $estado_old,
                    'tipo_gestion' => $tipo_gestion
                ]);

                $mensaje = "La suscripción ha sido cancelada. El registro de la venta se ha mantenido.";
                $tipo_mensaje = 'info';

            } elseif ($tipo_gestion === 'eliminar_con_reembolso') {
                // Opción 2: Eliminar permanentemente (implica reembolso)
                if ($estado_old == 1) {
                    ajustarPerfilesDisponibles($pdo, $cm_id, 'incrementar', $id_usuario_sesion, $rol_usuario_sesion);
                }

                $sqlD = "DELETE FROM perfiles_vendidos WHERE id_perfil_vendido = :idp";
                $pD   = [':idp' => $id_perfil];
                if (!in_array($rol_usuario_sesion, ['superadmin', 'admin', 'cortes'])) { $sqlD .= " AND id_usuario = :owner"; $pD[':owner'] = $id_usuario_sesion; }
                $d = $pdo->prepare($sqlD);
                if (!$d->execute($pD)) { error_log("Eliminar (gestionar) error: " . json_encode($d->errorInfo())); throw new Exception("No se pudo eliminar la suscripción."); }

                // Auditoría
                audit($pdo, $id_usuario_sesion, $rol_usuario_sesion, 'delete', 'perfiles_vendidos', $id_perfil, [
                    'cuenta_maestra_id' => $cm_id,
                    'estado_anterior' => $estado_old,
                    'tipo_gestion' => $tipo_gestion
                ]);

                $mensaje = "Suscripción eliminada permanentemente (con reembolso).";
                $tipo_mensaje = 'success';
            } else {
                throw new Exception("Tipo de gestión no válido.");
            }
            break;
        }

        default:
            throw new Exception("Acción desconocida: " . htmlspecialchars($accion));
    }

    $pdo->commit();

} catch (PDOException $e) {
    if ($pdo->inTransaction()) $pdo->rollBack();
    error_log("PDO Error ({$accion}): " . $e->getMessage());
    $mensaje = "Error de base de datos: " . $e->getMessage(); $tipo_mensaje = 'danger';

    if (in_array($accion, ['agregar_perfil_vendido','editar_perfil_vendido','agregar_multiples_perfiles'])) {
        $_SESSION['form_error'] = $mensaje;
        $redirect_url = "/digitalpremium/pages/perfiles_vendidos_crear.php";
        if (!empty($isEditing) && isset($_POST['id_perfil_vendido'])) {
            $redirect_url .= "?editar_id=" . urlencode((string)$_POST['id_perfil_vendido']);
        }
    } else {
        $redirect_url = ($accion === 'renovar_desde_dashboard') ? "/digitalpremium/pages/dashboard2.php" : "/digitalpremium/pages/perfiles_vendidos.php";
    }

} catch (Exception $e) {
    if ($pdo->inTransaction()) $pdo->rollBack();
    error_log("Exception ({$accion}): " . $e->getMessage());
    $mensaje = "Error: " . $e->getMessage(); $tipo_mensaje = 'danger';

    if (in_array($accion, ['agregar_perfil_vendido','editar_perfil_vendido','agregar_multiples_perfiles'])) {
        $_SESSION['form_error'] = $mensaje;
        $redirect_url = "/digitalpremium/pages/perfiles_vendidos_crear.php";
        if (!empty($isEditing) && isset($_POST['id_perfil_vendido'])) {
            $redirect_url .= "?editar_id=" . urlencode((string)$_POST['id_perfil_vendido']);
        }
    } else {
        $redirect_url = ($accion === 'renovar_desde_dashboard') ? "/digitalpremium/pages/dashboard2.php" : "/digitalpremium/pages/perfiles_vendidos.php";
    }
}

// Mensaje post-compra (modal) tras crear
if (in_array($accion, ['agregar_multiples_perfiles','agregar_perfil_vendido']) && $tipo_mensaje === 'success' && !empty($created_profile_ids)) {
    $_SESSION['mensaje_post_compra_para_copiar'] = generarMensajeParaCliente(
        $pdo,
        $created_profile_ids,
        $id_usuario_sesion,
        'bienvenida',
        $_POST['tipo_mensaje_activacion'] ?? 'perfil_con_pass'
    );

    if (isset($_POST['id_cliente'])) {
        $stTel = $pdo->prepare("SELECT telefono FROM clientes WHERE id_cliente = :idc");
        $stTel->execute([':idc' => (int)$_POST['id_cliente']]);
        $tel = $stTel->fetchColumn();
        $_SESSION['telefono_cliente_para_whatsapp'] = $tel ? limpiarNumeroWhatsApp($tel) : '';
    }
    error_log("DEBUG Controlador - Acción exitosa (agregar): $accion, llamando a preservarFiltrosEnRedireccion()");
    $filtros_preservados = preservarFiltrosEnRedireccion();
    error_log("DEBUG Controlador - Filtros preservados (agregar): $filtros_preservados");
    $redirect_url = "/digitalpremium/pages/perfiles_vendidos.php" . $filtros_preservados;
    error_log("DEBUG Controlador - URL de redirección final (agregar): $redirect_url");
} elseif ($accion === 'renovar_desde_dashboard' && $tipo_mensaje === 'success') {
    $redirect_url = "/digitalpremium/pages/dashboard2.php";
} elseif (in_array($accion, ['editar_perfil_vendido','renovar','cancelar_suscripcion','eliminar_permanente']) && $tipo_mensaje === 'success') {
    error_log("DEBUG Controlador - Acción exitosa: $accion, llamando a preservarFiltrosEnRedireccion()");
    $filtros_preservados = preservarFiltrosEnRedireccion();
    error_log("DEBUG Controlador - Filtros preservados: $filtros_preservados");
    $redirect_url = "/digitalpremium/pages/perfiles_vendidos.php" . $filtros_preservados;
    error_log("DEBUG Controlador - URL de redirección final: $redirect_url");
}

error_log("DEBUG Controlador - FINALIZANDO - URL de redirección: $redirect_url");
error_log("DEBUG Controlador - FINALIZANDO - Mensaje: $mensaje, Tipo: $tipo_mensaje");

header("Location: {$redirect_url}?mensaje=" . urlencode($mensaje) . "&tipo=" . urlencode($tipo_mensaje));
exit();
