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

if (session_status() == PHP_SESSION_NONE) {
    session_start();
}

// --- Auth ---
if (!isset($_SESSION['id_usuario'])) {
    if (isset($_POST['ajax_request'])) {
        header('Content-Type: application/json; charset=utf-8');
        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/tenant_helper.php'; // para get_data_owner_id($pdo)
require_once '../includes/audit_helper.php'; // Auditoría de acciones

// ---- Utilidades de rol ----
function normalize_role($rol) {
    $r = strtolower(trim((string)$rol));
    if ($r === 'super_admin') $r = 'superadmin';
    return $r;
}
function is_admin_total($rol) {
    $r = normalize_role($rol);
    return in_array($r, ['superadmin','admin'], true);
}
function can_create_cliente($rol) {
    $r = normalize_role($rol);
    return in_array($r, ['superadmin','admin','ventas'], true); // cortes NO
}
function can_edit_cliente($rol) {
    $r = normalize_role($rol);
    return in_array($r, ['superadmin','admin','ventas'], true); // cortes NO
}
function can_change_estado($rol) {
    $r = normalize_role($rol);
    return in_array($r, ['superadmin','admin'], true); // ventas/cortes NO
}

// ---- Entradas base ----
$accion               = $_POST['accion'] ?? $_GET['accion'] ?? null;
$id_usuario_sesion    = (int)$_SESSION['id_usuario'];
$rol_usuario_sesion   = $_SESSION['rol'] ?? 'ventas';
$rol_norm             = normalize_role($rol_usuario_sesion);
$OWNER_ID             = get_data_owner_id($pdo); // clientes compartidos (multi-usuario)

// form / ajax
$is_ajax      = isset($_POST['ajax_request']) && $_POST['ajax_request'] == '1';
$mensaje      = '';
$tipo_mensaje = 'danger';

// Helper de normalización local de teléfonos (solo dígitos)
$norm = function (?string $t): string {
    return preg_replace('/\D+/', '', (string)$t ?? '');
};

// Expresión SQL para normalizar teléfono en BD (remueve + - espacio ( ) .)
$sql_norm_tel = "REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(telefono,'+',''),'-',''),' ',''),'(',''),')',''),'.','')";

try {
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $pdo->beginTransaction();
    }

    switch ($accion) {

        // ===========================================================
        // AGREGAR
        // ===========================================================
        case 'agregar': {
            if (!can_create_cliente($rol_norm)) {
                throw new Exception("No tienes permisos para agregar clientes.");
            }

            $nombre   = trim($_POST['nombre_completo'] ?? '');
            $telefono = trim($_POST['telefono'] ?? '');
            $email    = trim($_POST['email'] ?? '');
            $notas    = trim($_POST['notas_cliente'] ?? '');
            $estado   = 1; // por defecto activo

            if ($nombre === '')  throw new Exception("El nombre completo del cliente es obligatorio.");
            if ($telefono === '') throw new Exception("El número de teléfono es obligatorio.");

            $tel_norm = $norm($telefono);
            if ($tel_norm === '' || strlen($tel_norm) < 9 || strlen($tel_norm) > 15) {
                throw new Exception("El teléfono debe contener solo dígitos (9 a 15).");
            }
            if ($email !== '' && filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
                throw new Exception("El formato del email no es válido.");
            }

            // Duplicado global por teléfono (normalizado) — sin filtrar por id_usuario
            $sqlDup = $pdo->prepare("SELECT id_cliente FROM clientes WHERE {$sql_norm_tel} = :t LIMIT 1");
            $sqlDup->execute([':t' => $tel_norm]);
            if ($sqlDup->fetchColumn()) {
                throw new Exception("Ya existe un cliente con ese número de teléfono.");
            }

            // Insert bajo OWNER_ID para que sea compartido por todos
            $sql = "INSERT INTO clientes (id_usuario, nombre_completo, telefono, email, notas_cliente, estado_cliente)
                    VALUES (:id_owner, :nombre, :telefono, :email, :notas, :estado)";
            $stmt = $pdo->prepare($sql);
            $stmt->execute([
                ':id_owner'  => $OWNER_ID,
                ':nombre'    => $nombre,
                ':telefono'  => $telefono, // guardamos como lo escribió el usuario
                ':email'     => ($email === '' ? null : $email),
                ':notas'     => ($notas === '' ? null : $notas),
                ':estado'    => $estado
            ]);
            $id_nuevo_cliente = $pdo->lastInsertId();

            // Auditoría
            audit($pdo, $id_usuario_sesion, $rol_usuario_sesion, 'create', 'clientes', $id_nuevo_cliente, [
                'nombre' => $nombre,
                'telefono' => $telefono,
                'email' => $email
            ]);

            if ($is_ajax) {
                if ($pdo->inTransaction()) $pdo->commit();
                header('Content-Type: application/json; charset=utf-8');
                echo json_encode([
                    'success' => true,
                    'message' => 'Cliente agregado exitosamente.',
                    'cliente' => [
                        'id_cliente'     => $id_nuevo_cliente,
                        'nombre_completo'=> $nombre,
                        'telefono'       => $telefono,
                        'email'          => ($email === '' ? null : $email),
                    ]
                ]);
                exit();
            }

            $mensaje = "Cliente agregado exitosamente.";
            $tipo_mensaje = 'success';
            break;
        }

        // ===========================================================
        // EDITAR
        // ===========================================================
        case 'editar': {
            if (!can_edit_cliente($rol_norm)) {
                throw new Exception("No tienes permisos para editar clientes.");
            }

            $id_cliente = isset($_POST['id_cliente']) ? filter_var($_POST['id_cliente'], FILTER_VALIDATE_INT) : false;
            if ($id_cliente === false) throw new Exception("ID de cliente inválido.");

            $nombre   = trim($_POST['nombre_completo'] ?? '');
            $telefono = trim($_POST['telefono'] ?? '');
            $email    = trim($_POST['email'] ?? '');
            $notas    = trim($_POST['notas_cliente'] ?? '');
            $estado   = isset($_POST['estado_cliente']) ? filter_var($_POST['estado_cliente'], FILTER_VALIDATE_INT) : null;

            if ($nombre === '')   throw new Exception("El nombre completo del cliente es obligatorio.");
            if ($telefono === '') throw new Exception("El número de teléfono es obligatorio.");

            $tel_norm = $norm($telefono);
            if ($tel_norm === '' || strlen($tel_norm) < 9 || strlen($tel_norm) > 15) {
                throw new Exception("El teléfono debe contener solo dígitos (9 a 15).");
            }
            if ($email !== '' && filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
                throw new Exception("El formato del email no es válido.");
            }

            // Duplicado por teléfono en otro cliente (global, sin id_usuario)
            $sqlDup = $pdo->prepare("SELECT id_cliente FROM clientes WHERE {$sql_norm_tel} = :t AND id_cliente <> :id LIMIT 1");
            $sqlDup->execute([':t' => $tel_norm, ':id' => $id_cliente]);
            if ($sqlDup->fetchColumn()) {
                throw new Exception("Ya existe otro cliente con ese número de teléfono.");
            }

            // Si no es admin total, NO puede cambiar estado: mantener el actual
            if (!is_admin_total($rol_norm)) {
                $stmtCur = $pdo->prepare("SELECT estado_cliente FROM clientes WHERE id_cliente = :id");
                $stmtCur->execute([':id' => $id_cliente]);
                $estado_actual = $stmtCur->fetchColumn();
                if ($estado_actual === false) throw new Exception("Cliente no encontrado.");
                $estado = (int)$estado_actual;
            } else {
                if ($estado === false || !in_array($estado, [0,1], true)) {
                    throw new Exception("Estado de cliente inválido.");
                }
            }

            // Update (global, sin filtrar por id_usuario)
            $sql = "UPDATE clientes
                       SET nombre_completo = :nombre,
                           telefono        = :telefono,
                           email           = :email,
                           notas_cliente   = :notas,
                           estado_cliente  = :estado
                     WHERE id_cliente = :id_cliente";
            $stmt = $pdo->prepare($sql);
            $stmt->execute([
                ':nombre'      => $nombre,
                ':telefono'    => $telefono,
                ':email'       => ($email === '' ? null : $email),
                ':notas'       => ($notas === '' ? null : $notas),
                ':estado'      => $estado,
                ':id_cliente'  => $id_cliente
            ]);

            // Auditoría
            audit($pdo, $id_usuario_sesion, $rol_usuario_sesion, 'update', 'clientes', $id_cliente, [
                'nombre' => $nombre,
                'telefono' => $telefono,
                'email' => $email,
                'estado' => $estado
            ]);

            if ($is_ajax) {
                if ($pdo->inTransaction()) $pdo->commit();
                header('Content-Type: application/json; charset=utf-8');
                echo json_encode([
                    'success' => true,
                    'message' => 'Cliente actualizado exitosamente.',
                    'cliente' => [
                        'id_cliente'      => $id_cliente,
                        'nombre_completo' => $nombre,
                        'telefono'        => $telefono,
                        'email'           => ($email === '' ? null : $email),
                        'estado_cliente'  => $estado
                    ]
                ]);
                exit();
            }

            $mensaje = "Cliente actualizado exitosamente.";
            $tipo_mensaje = 'success';
            break;
        }

        // ===========================================================
        // CAMBIAR ESTADO (alta/baja)
        // ===========================================================
        case 'cambiar_estado': {
            if (!can_change_estado($rol_norm)) {
                throw new Exception("No tienes permisos para cambiar el estado del cliente.");
            }

            if (empty($_POST['id_cliente']) || !isset($_POST['nuevo_estado'])) {
                throw new Exception("ID de cliente o nuevo estado no proporcionado.");
            }

            $id_cliente   = filter_var($_POST['id_cliente'], FILTER_VALIDATE_INT);
            $nuevo_estado = filter_var($_POST['nuevo_estado'], FILTER_VALIDATE_INT);
            if ($id_cliente === false || ($nuevo_estado !== 0 && $nuevo_estado !== 1)) {
                throw new Exception("ID o estado inválido.");
            }

            $stmt = $pdo->prepare("UPDATE clientes SET estado_cliente = :nuevo_estado WHERE id_cliente = :id_cliente");
            $stmt->execute([':nuevo_estado' => $nuevo_estado, ':id_cliente' => $id_cliente]);

            // Auditoría
            audit($pdo, $id_usuario_sesion, $rol_usuario_sesion, 'update', 'clientes', $id_cliente, [
                'accion' => 'cambiar_estado',
                'nuevo_estado' => $nuevo_estado
            ]);

            if ($is_ajax) {
                if ($pdo->inTransaction()) $pdo->commit();
                header('Content-Type: application/json; charset=utf-8');
                echo json_encode([
                    'success' => true,
                    'message' => 'Estado actualizado.',
                    'cliente' => [
                        'id_cliente'     => $id_cliente,
                        'estado_cliente' => $nuevo_estado
                    ]
                ]);
                exit();
            }

            $mensaje = "Estado del cliente actualizado exitosamente.";
            $tipo_mensaje = 'success';
            break;
        }

        default:
            throw new Exception("Acción no reconocida.");
    }

    if ($pdo->inTransaction()) {
        $pdo->commit();
    }

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

    $mensaje = ($e->getCode() == '23000')
        ? "Error de integridad de datos (posible duplicado)."
        : "Error de base de datos.";
    error_log("PDOException (clientes_controlador {$accion}) uid={$id_usuario_sesion}: " . $e->getMessage());

    if ($is_ajax) {
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode(['success' => false, 'message' => $mensaje]);
        exit();
    }

    $tipo_mensaje = 'danger';

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

    $mensaje = $e->getMessage();
    error_log("Exception (clientes_controlador {$accion}) uid={$id_usuario_sesion}: " . $mensaje);

    if ($is_ajax) {
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode(['success' => false, 'message' => $mensaje]);
        exit();
    }

    $tipo_mensaje = 'danger';
}

// Redirección para formularios normales (NO AJAX)
if (!$is_ajax) {
    header("Location: /digitalpremium/pages/clientes.php?mensaje=" . urlencode($mensaje) . "&tipo=" . urlencode($tipo_mensaje));
    exit();
}
