<?php
// FILE: /digitalpremium/actions/cuentas_maestras_controlador.php

if (session_status() == PHP_SESSION_NONE) {
    session_start();
}
if (!isset($_SESSION['id_usuario'])) {
    if (!empty($_POST['ajax_request'])) {
        header('Content-Type: application/json');
        echo json_encode(['success' => false, 'message' => 'Acceso no autorizado. Sesión expirada.']);
        exit();
    }
    header("Location: /digitalpremium/login.php?error=" . urlencode("Acceso no autorizado"));
    exit();
}

require_once '../config/db.php';
require_once '../includes/audit_helper.php'; // Auditoría de acciones

$accion               = $_POST['accion'] ?? $_GET['accion'] ?? null;
$is_ajax              = !empty($_POST['ajax_request']) && $_POST['ajax_request'] == '1';
$id_usuario_sesion    = (int)$_SESSION['id_usuario'];
$rol_usuario_sesion   = strtolower(trim($_SESSION['rol'] ?? 'ventas')); // normaliza
$redirect_url         = "/digitalpremium/pages/cuentas_maestras.php";

/* ===================== HELPERS DE RESPUESTA ===================== */
// 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');
}

function jsonExit($ok, $msg, $extra = []) {
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(array_merge(['success' => $ok, 'message' => $msg], $extra));
    exit();
}
function parseDateOrNull(?string $d): ?string {
    if (!$d) return null;
    $dt = DateTime::createFromFormat('Y-m-d', $d);
    return ($dt && $dt->format('Y-m-d') === $d) ? $d : null;
}
function assertDateOrThrow(string $value, string $label): string {
    $ok = parseDateOrNull($value);
    if (!$ok) throw new Exception("Fecha inválida: {$label}.");
    return $ok;
}

/* ===================== PERMISOS POR ROL (SOLO ESTE MÓDULO) ===================== */
/**
 * Acciones: create | edit | renew | delete
 */
function canActOnCuentas(string $role, string $action): bool {
    $r = strtolower(trim($role));
    if ($r === 'super_admin') $r = 'superadmin';

    switch ($r) {
        case 'superadmin':
        case 'admin':
            return in_array($action, ['create','edit','renew','delete'], true);
        case 'ventas':
            return in_array($action, ['create','edit','renew'], true); // NO delete
        case 'cortes':
            return in_array($action, ['edit'], true); // NO create, NO renew, NO delete, SÍ edit
        default:
            return false;
    }
}
function requireCanOrExit(string $action, bool $is_ajax) {
    global $rol_usuario_sesion;
    if (!canActOnCuentas($rol_usuario_sesion, $action)) {
        $msg = "Permiso denegado (cuentas_maestras/$action).";
        if ($is_ajax) { jsonExit(false, $msg); }
        header("Location: /digitalpremium/pages/cuentas_maestras.php?mensaje=" . urlencode($msg) . "&tipo=danger");
        exit();
    }
}

/* ===================== CONTROLADOR ===================== */
try {
    if (!$accion) {
        throw new Exception("Acción no proporcionada.");
    }

    // Todas estas acciones escriben en BD: transacción
    $pdo->beginTransaction();

    switch ($accion) {

        /* ===================== AGREGAR ===================== */
        case 'agregar': {
            requireCanOrExit('create', $is_ajax);

            // Requeridos
            $id_plataforma  = filter_var($_POST['id_plataforma'] ?? null, FILTER_VALIDATE_INT);
            $email_cuenta   = trim($_POST['email_cuenta'] ?? '');
            $password_raw   = trim($_POST['password_cuenta'] ?? '');
            $perfiles_total = filter_var($_POST['perfiles_total'] ?? null, FILTER_VALIDATE_INT);
            $fecha_venc     = $_POST['fecha_vencimiento_proveedor'] ?? null;

            if (!$id_plataforma || $email_cuenta === '' || $password_raw === '' || !$perfiles_total || !$fecha_venc) {
                throw new Exception("Faltan campos requeridos.");
            }

            // Validar fechas
            $fecha_venc   = assertDateOrThrow($fecha_venc, "Fecha de vencimiento");
            $fecha_compra = parseDateOrNull($_POST['fecha_compra_proveedor'] ?? null);
            if ($fecha_compra && $fecha_venc < $fecha_compra) {
                throw new Exception("La fecha de vencimiento no puede ser anterior a la fecha de compra.");
            }

            // Duplicado GLOBAL (misma plataforma + email) - Solo si la cuenta existente está ACTIVA
            $dup = $pdo->prepare("
                SELECT 1
                FROM cuentas_maestras
                WHERE id_plataforma = :p AND email_cuenta = :e AND estado_cuenta = 1
                LIMIT 1
            ");
            $dup->execute([':p'=>$id_plataforma, ':e'=>$email_cuenta]);
            if ($dup->fetch()) {
                throw new Exception("Ya existe una cuenta ACTIVA de esa plataforma con ese correo/usuario.");
            }

            // Datos opcionales
            $nombre_proveedor = trim($_POST['nombre_proveedor'] ?? '');
            $costo_compra     = $_POST['costo_compra'] ?? null;
            $costo_compra     = ($costo_compra === null || $costo_compra === '') ? null
                                : filter_var(str_replace(',', '.', $costo_compra), FILTER_VALIDATE_FLOAT);
            $notas_cuenta     = trim($_POST['notas_cuenta'] ?? '');
            $estado_cuenta    = filter_var($_POST['estado_cuenta'] ?? 1, FILTER_VALIDATE_INT);
            if (!in_array($estado_cuenta, [0,1,2], true)) $estado_cuenta = 1;

            $sql = "INSERT INTO cuentas_maestras
                    (id_usuario, id_plataforma, email_cuenta, password_cuenta, nombre_proveedor, fecha_compra_proveedor,
                     fecha_vencimiento_proveedor, costo_compra, perfiles_total, perfiles_disponibles, notas_cuenta, estado_cuenta)
                    VALUES
                    (:id_usuario, :id_plataforma, :email_cuenta, :password_cuenta, :nombre_proveedor, :fecha_compra,
                     :fecha_venc, :costo_compra, :perfiles_total, :perfiles_disponibles, :notas_cuenta, :estado_cuenta)";
            $stmt = $pdo->prepare($sql);
            $stmt->execute([
                ':id_usuario'            => $id_usuario_sesion,
                ':id_plataforma'         => $id_plataforma,
                ':email_cuenta'          => $email_cuenta,
                ':password_cuenta'       => $password_raw, // (Opcional: cifrar con openssl_encrypt)
                ':nombre_proveedor'      => $nombre_proveedor !== '' ? $nombre_proveedor : null,
                ':fecha_compra'          => $fecha_compra,
                ':fecha_venc'            => $fecha_venc,
                ':costo_compra'          => $costo_compra,
                ':perfiles_total'        => $perfiles_total,
                ':perfiles_disponibles'  => $perfiles_total, // recién creada
                ':notas_cuenta'          => $notas_cuenta !== '' ? $notas_cuenta : null,
                ':estado_cuenta'         => $estado_cuenta
            ]);

            $id_new = $pdo->lastInsertId();
            
            // Auditoría
            audit($pdo, $id_usuario_sesion, $rol_usuario_sesion, 'create', 'cuentas_maestras', $id_new, [
                'plataforma_id' => $id_plataforma,
                'email' => $email_cuenta,
                'perfiles_total' => $perfiles_total,
                'estado' => $estado_cuenta
            ]);
            
            $pdo->commit();

            if ($is_ajax) {
                jsonExit(true, 'Cuenta maestra agregada exitosamente.', [
                    'data' => [
                        'id_cuenta_maestra'    => $id_new,
                        'id_plataforma'        => $id_plataforma,
                        'email_cuenta'         => $email_cuenta,
                        'perfiles_disponibles' => $perfiles_total
                    ]
                ]);
            }

            $mensaje = "Cuenta maestra agregada exitosamente.";
            $tipo_mensaje = 'success';
            break;
        }

        /* ===================== EDITAR ===================== */
        case 'editar': {
            requireCanOrExit('edit', $is_ajax);

            $id_cuenta = filter_var($_POST['id_cuenta_maestra'] ?? null, FILTER_VALIDATE_INT);
            if (!$id_cuenta) throw new Exception("ID de cuenta inválido para edición.");

            // Cargar cuenta SIN filtrar por dueño
            $stmt_old = $pdo->prepare("SELECT id_usuario, id_plataforma, email_cuenta, password_cuenta FROM cuentas_maestras WHERE id_cuenta_maestra = :id");
            $stmt_old->execute([':id' => $id_cuenta]);
            $old = $stmt_old->fetch(PDO::FETCH_ASSOC);
            if (!$old) throw new Exception("Cuenta no encontrada para editar.");

            // Datos recibidos
            $id_plataforma    = filter_var($_POST['id_plataforma'] ?? null, FILTER_VALIDATE_INT);
            $email_cuenta     = trim($_POST['email_cuenta'] ?? '');
            $password_new     = trim($_POST['password_cuenta'] ?? '');
            $nombre_proveedor = trim($_POST['nombre_proveedor'] ?? '');
            $fecha_compra     = parseDateOrNull($_POST['fecha_compra_proveedor'] ?? null);
            $fecha_venc       = $_POST['fecha_vencimiento_proveedor'] ?? null;
            $fecha_venc       = assertDateOrThrow($fecha_venc, "Fecha de vencimiento");
            if ($fecha_compra && $fecha_venc < $fecha_compra) {
                throw new Exception("La fecha de vencimiento no puede ser anterior a la fecha de compra.");
            }
            $costo_compra    = $_POST['costo_compra'] ?? null;
            $costo_compra    = ($costo_compra === null || $costo_compra === '') ? null
                               : filter_var(str_replace(',', '.', $costo_compra), FILTER_VALIDATE_FLOAT);
            $perfiles_total  = filter_var($_POST['perfiles_total'] ?? null, FILTER_VALIDATE_INT);
            $notas_cuenta    = trim($_POST['notas_cuenta'] ?? '');
            $estado_cuenta   = filter_var($_POST['estado_cuenta'] ?? 1, FILTER_VALIDATE_INT);
            if (!in_array($estado_cuenta, [0,1,2], true)) $estado_cuenta = 1;

            if (!$id_plataforma || $email_cuenta === '' || !$perfiles_total) {
                throw new Exception("Faltan campos requeridos.");
            }

            // Detectar cambios importantes (SOLO email y contraseña)
            $cambios_detectados = [];
            $datos_cambios = [];
            
            $email_cambiado = ($old['email_cuenta'] !== $email_cuenta);
            $password_cambiado = ($password_new !== '' && $old['password_cuenta'] !== $password_new);
            
            // Debug: Log de cambios detectados
            error_log("DEBUG CAMBIOS - Email anterior: " . $old['email_cuenta'] . " | Email nuevo: " . $email_cuenta . " | Email cambiado: " . ($email_cambiado ? 'SI' : 'NO'));
            error_log("DEBUG CAMBIOS - Password anterior: " . $old['password_cuenta'] . " | Password nuevo: " . $password_new . " | Password cambiado: " . ($password_cambiado ? 'SI' : 'NO'));
            
            // Siempre incluir los valores actuales de email y contraseña para el modal
            $datos_cambios['email_actual'] = $email_cuenta;
            $datos_cambios['password_actual'] = $password_new ?: $old['password_cuenta'];
            
            // Si ambos cambian, usar tipo especial "correo + contraseña"
            if ($email_cambiado && $password_cambiado) {
                $cambios_detectados[] = 'correo_password';
                $datos_cambios['email_anterior'] = $old['email_cuenta'];
                $datos_cambios['email_nuevo'] = $email_cuenta;
                $datos_cambios['password_cambiada'] = true;
                $datos_cambios['password_nueva'] = $password_new;
                error_log("DEBUG CAMBIOS - Tipo detectado: correo_password");
            } else {
                // Cambios individuales
                if ($email_cambiado) {
                    $cambios_detectados[] = 'email';
                    $datos_cambios['email_anterior'] = $old['email_cuenta'];
                    $datos_cambios['email_nuevo'] = $email_cuenta;
                    error_log("DEBUG CAMBIOS - Tipo detectado: email");
                }
                
                if ($password_cambiado) {
                    $cambios_detectados[] = 'password';
                    $datos_cambios['password_cambiada'] = true;
                    $datos_cambios['password_nueva'] = $password_new;
                    error_log("DEBUG CAMBIOS - Tipo detectado: password");
                }
            }
            
            error_log("DEBUG CAMBIOS - Cambios detectados: " . json_encode($cambios_detectados));
            
            // NOTA: Solo se detectan cambios en email y contraseña para mostrar el modal de aviso
            // Otros cambios como plataforma, estado, fechas, notas, costo, perfiles, etc. NO generan modal de aviso
            // Esto es porque solo los cambios de credenciales requieren notificación a los clientes

            // Duplicado GLOBAL (plataforma + login) excluyendo la propia cuenta - Solo si la cuenta existente está ACTIVA
            $dup = $pdo->prepare("
                SELECT 1
                FROM cuentas_maestras
                WHERE id_plataforma = :p
                  AND email_cuenta  = :e
                  AND id_cuenta_maestra <> :id
                  AND estado_cuenta = 1
                LIMIT 1
            ");
            $dup->execute([
                ':p'  => $id_plataforma,
                ':e'  => $email_cuenta,
                ':id' => $id_cuenta
            ]);
            if ($dup->fetch()) {
                throw new Exception("Ya existe otra cuenta ACTIVA de esa plataforma con ese correo/usuario.");
            }

            // Ocupados actuales (solo activos - los cancelados liberan espacio)
            $stmt_ocu = $pdo->prepare("SELECT COUNT(*) FROM perfiles_vendidos WHERE id_cuenta_maestra = :id AND estado_suscripcion = 1");
            $stmt_ocu->execute([':id' => $id_cuenta]);
            $ocupados = (int)$stmt_ocu->fetchColumn();

            if ($perfiles_total < $ocupados) {
                throw new Exception("No puedes establecer $perfiles_total perfiles totales: ya hay $ocupados perfiles activos vendidos.");
            }
            $perfiles_disponibles = max(0, $perfiles_total - $ocupados);

            // Update (SIN filtro por dueño)
            $sql = "UPDATE cuentas_maestras
                    SET id_plataforma = :id_plataforma,
                        email_cuenta  = :email_cuenta,
                        nombre_proveedor = :nombre_proveedor,
                        fecha_compra_proveedor = :fecha_compra,
                        fecha_vencimiento_proveedor = :fecha_venc,
                        costo_compra = :costo_compra,
                        perfiles_total = :perfiles_total,
                        perfiles_disponibles = :perfiles_disponibles,
                        notas_cuenta = :notas_cuenta,
                        estado_cuenta = :estado_cuenta";

            $params = [
                ':id_plataforma'        => $id_plataforma,
                ':email_cuenta'         => $email_cuenta,
                ':nombre_proveedor'     => $nombre_proveedor !== '' ? $nombre_proveedor : null,
                ':fecha_compra'         => $fecha_compra,
                ':fecha_venc'           => $fecha_venc,
                ':costo_compra'         => $costo_compra,
                ':perfiles_total'       => $perfiles_total,
                ':perfiles_disponibles' => $perfiles_disponibles,
                ':notas_cuenta'         => $notas_cuenta !== '' ? $notas_cuenta : null,
                ':estado_cuenta'        => $estado_cuenta,
                ':id'                   => $id_cuenta
            ];

            if ($password_new !== '') {
                $sql .= ", password_cuenta = :password_cuenta";
                $params[':password_cuenta'] = $password_new; // (Opcional: cifrado)
            }

            $sql .= " WHERE id_cuenta_maestra = :id";

            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);

            // Auditoría
            audit($pdo, $id_usuario_sesion, $rol_usuario_sesion, 'update', 'cuentas_maestras', $id_cuenta, [
                'plataforma_id' => $id_plataforma,
                'email' => $email_cuenta,
                'perfiles_total' => $perfiles_total,
                'estado' => $estado_cuenta
            ]);

            $pdo->commit();

            // Si hay cambios SENSIBLES (email o contraseña), obtener clientes vinculados para notificación
            $clientes_vinculados = [];
            $nombre_plataforma = '';
            if (!empty($cambios_detectados)) {
                // Obtener nombre de la plataforma
                $stmt_plataforma = $pdo->prepare("
                    SELECT p.nombre_plataforma 
                    FROM plataformas p 
                    WHERE p.id_plataforma = :id_plataforma
                ");
                $stmt_plataforma->execute([':id_plataforma' => $id_plataforma]);
                $plataforma_data = $stmt_plataforma->fetch(PDO::FETCH_ASSOC);
                $nombre_plataforma = $plataforma_data ? $plataforma_data['nombre_plataforma'] : '';
                
                $stmt_clientes = $pdo->prepare("
                    SELECT DISTINCT 
                        c.id_cliente,
                        c.nombre_completo,
                        c.telefono,
                        c.email,
                        pv.nombre_perfil_cliente,
                        pv.fecha_fin_servicio
                    FROM perfiles_vendidos pv
                    JOIN clientes c ON pv.id_cliente = c.id_cliente
                    WHERE pv.id_cuenta_maestra = :id_cuenta 
                    AND pv.estado_suscripcion = 1
                    ORDER BY c.nombre_completo
                ");
                $stmt_clientes->execute([':id_cuenta' => $id_cuenta]);
                $clientes_vinculados = $stmt_clientes->fetchAll(PDO::FETCH_ASSOC);
            }

            if ($is_ajax) {
                jsonExit(true, "Cuenta actualizada exitosamente.", [
                    'data' => [
                        'id_cuenta_maestra'    => $id_cuenta,
                        'perfiles_total'       => $perfiles_total,
                        'perfiles_disponibles' => $perfiles_disponibles,
                        'estado_cuenta'        => $estado_cuenta,
                        'fecha_vencimiento'    => $fecha_venc,
                        'cambios_detectados'   => $cambios_detectados,
                        'datos_cambios'        => $datos_cambios,
                        'clientes_vinculados'  => $clientes_vinculados,
                        'plataforma'           => $nombre_plataforma
                    ]
                ]);
            }

            $mensaje = "Cuenta actualizada exitosamente.";
            $tipo_mensaje = 'success';
            break;
        }

        /* ===================== RENOVAR ===================== */
        case 'renovar': {
            requireCanOrExit('renew', $is_ajax);

            $id_cuenta  = filter_var($_POST['id_cuenta_maestra'] ?? null, FILTER_VALIDATE_INT);
            $fecha_venc = $_POST['fecha_vencimiento_proveedor'] ?? null;
            $costo_compra = $_POST['costo_compra'] ?? null;
            $notas_renovacion = trim($_POST['notas_renovacion'] ?? '');
            
            if (!$id_cuenta || !$fecha_venc) {
                throw new Exception("Datos incompletos para la renovación.");
            }

            // Validar fecha de vencimiento
            $fecha_venc = assertDateOrThrow($fecha_venc, "Fecha de vencimiento");
            $fecha_actual = getLocalDate();
            
            if ($fecha_venc <= $fecha_actual) {
                throw new Exception("La fecha de vencimiento debe ser posterior a la fecha actual.");
            }

            // Procesar costo de compra
            $costo_compra = ($costo_compra === null || $costo_compra === '') ? null
                            : filter_var(str_replace(',', '.', $costo_compra), FILTER_VALIDATE_FLOAT);
            
            if ($costo_compra !== null && $costo_compra < 0) {
                throw new Exception("El costo de compra no puede ser negativo.");
            }

            // Actualizar cuenta maestra
            $sql = "UPDATE cuentas_maestras
                    SET fecha_vencimiento_proveedor = :venc,
                        costo_compra = :costo,
                        fecha_compra_proveedor = :fecha_compra,
                        estado_cuenta = 1
                    WHERE id_cuenta_maestra = :id";
            
            $params = [
                ':venc' => $fecha_venc, 
                ':costo' => $costo_compra, 
                ':fecha_compra' => $fecha_actual, 
                ':id' => $id_cuenta
            ];

            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);

            if ($stmt->rowCount() === 0) {
                throw new Exception("No se pudo actualizar la cuenta durante la renovación.");
            }

            // REGISTRAR LA RENOVACIÓN COMO EGRESO EN FINANZAS
            // Los egresos se calculan automáticamente desde la tabla cuentas_maestras
            // sumando todos los costos de compra y renovación

            // Auditoría detallada para contabilidad
            audit($pdo, $id_usuario_sesion, $rol_usuario_sesion, 'renovar', 'cuentas_maestras', $id_cuenta, [
                'fecha_vencimiento_nueva' => $fecha_venc,
                'costo_compra' => $costo_compra,
                'notas_renovacion' => $notas_renovacion,
                'tipo_operacion' => 'renovacion_cuenta_maestra',
                'categoria_gasto' => 'Renovaciones Cuentas Maestras',
                'monto_egreso' => $costo_compra
            ]);

            $pdo->commit();

            if ($is_ajax) {
                jsonExit(true, "Cuenta renovada exitosamente.", [
                    'data' => ['id_cuenta_maestra' => $id_cuenta, 'fecha_vencimiento' => $fecha_venc]
                ]);
            }

            $mensaje = "Cuenta renovada exitosamente.";
            $tipo_mensaje = 'success';
            break;
        }

        /* ===================== ELIMINAR PERMANENTE ===================== */
        case 'eliminar_permanente': {
            requireCanOrExit('delete', $is_ajax); // Solo superadmin/admin

            $id_cuenta = filter_var($_POST['id_cuenta_maestra'] ?? null, FILTER_VALIDATE_INT);
            if (!$id_cuenta) throw new Exception("ID de cuenta inválido para eliminar.");

            // ¿Hay perfiles vendidos?
            $stmt_cnt = $pdo->prepare("SELECT COUNT(*) FROM perfiles_vendidos WHERE id_cuenta_maestra = :id");
            $stmt_cnt->execute([':id' => $id_cuenta]);
            $tiene_perfiles = (int)$stmt_cnt->fetchColumn();

            $forzar = !empty($_POST['forzar']) && $_POST['forzar'] == '1';

            if ($tiene_perfiles > 0 && !$forzar) {
                throw new Exception("La cuenta tiene perfiles asociados. Marca 'Eliminar permanentemente' (forzar) para continuar.");
            }

            if ($forzar) {
                $del_prof = $pdo->prepare("DELETE FROM perfiles_vendidos WHERE id_cuenta_maestra = :id");
                $del_prof->execute([':id' => $id_cuenta]);
            }

            // Eliminar cuenta (SIN filtro por dueño)
            $sql = "DELETE FROM cuentas_maestras WHERE id_cuenta_maestra = :id";
            $del_master = $pdo->prepare($sql);
            $del_master->execute([':id' => $id_cuenta]);

            if ($del_master->rowCount() === 0) {
                throw new Exception("No se pudo eliminar la cuenta (no existe).");
            }

            // Auditoría
            audit($pdo, $id_usuario_sesion, $rol_usuario_sesion, 'delete', 'cuentas_maestras', $id_cuenta, [
                'forzar' => $forzar,
                'tenia_perfiles' => $tiene_perfiles > 0
            ]);

            $pdo->commit();

            if ($is_ajax) {
                jsonExit(true, "Cuenta eliminada permanentemente.", ['data' => ['id_cuenta_maestra' => $id_cuenta]]);
            }

            $mensaje = "Cuenta eliminada permanentemente.";
            $tipo_mensaje = 'success';
            break;
        }

        default:
            throw new Exception("Acción no reconocida: '{$accion}'");
    }

} catch (PDOException $e) {
    if ($pdo && $pdo->inTransaction()) $pdo->rollBack();

    // Duplicado (índice UNIQUE)
    if ($e->getCode() === '23000') {
        $mensaje = "No se puede guardar: ya existe una cuenta de esa plataforma con ese correo/usuario.";
    } else {
        $mensaje = "Error de base de datos.";
    }
    error_log("PDOException ({$accion}) uid={$id_usuario_sesion}: " . $e->getMessage());

    if ($is_ajax) jsonExit(false, $mensaje);

    $tipo_mensaje = 'danger';

} catch (Exception $e) {
    if ($pdo && $pdo->inTransaction()) $pdo->rollBack();
    $mensaje = $e->getMessage();
    error_log("Exception ({$accion}) uid={$id_usuario_sesion}: " . $mensaje);

    if ($is_ajax) jsonExit(false, $mensaje);

    $tipo_mensaje = 'danger';
}

// Respuesta estándar por redirección (cuando NO es AJAX)
header("Location: {$redirect_url}?mensaje=" . urlencode($mensaje) . "&tipo=" . urlencode($tipo_mensaje));
exit();
