<?php
/**
 * Módulo Leads - Endpoint AJAX para agregar actividad (llamada, email, reunión, tarea, nota)
 */

// Cargar dependencias y sesión
if (!defined('BASE_PATH')) {
    define('BASE_PATH', dirname(dirname(__DIR__)));
}
require_once BASE_PATH . '/database/config.php';
require_once BASE_PATH . '/database/connection.php';
if (session_status() === PHP_SESSION_NONE) { session_start(); }

// Función de autenticación (definida si no existe)
if (!function_exists('isLoggedIn')) {
    function isLoggedIn() {
        return isset($_SESSION['user_id']) && !empty($_SESSION['user_id']);
    }
}

header('Content-Type: application/json; charset=utf-8');

if (!isLoggedIn()) {
    http_response_code(401);
    echo json_encode(['ok' => false, 'error' => 'No autorizado']);
    exit;
}

$db = getDB();

$lead_id = intval($_POST['lead_id'] ?? 0);
$type = strtolower(trim($_POST['type'] ?? ''));
$subject = trim($_POST['subject'] ?? '');
$description = trim($_POST['description'] ?? '');
$scheduled_at = trim($_POST['scheduled_at'] ?? '');
$status = trim($_POST['status'] ?? '');
// Duración en minutos para validar solapamientos (por defecto 30)
$duration_min = intval($_POST['duration_min'] ?? 30);
if ($duration_min <= 0) { $duration_min = 30; }

if ($lead_id <= 0) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'lead_id inválido']);
    exit;
}

$allowed_types = ['call','email','meeting','task','note','system'];
if (!in_array($type, $allowed_types, true)) {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'Tipo inválido']);
    exit;
}

if ($subject === '') {
    http_response_code(400);
    echo json_encode(['ok' => false, 'error' => 'El asunto es obligatorio']);
    exit;
}

// Validar existencia del lead
$lead = $db->selectOne('SELECT id FROM leads WHERE id = ?', [$lead_id]);
if (!$lead) {
    http_response_code(404);
    echo json_encode(['ok' => false, 'error' => 'Lead no encontrado']);
    exit;
}

// Determinar estado por defecto si no se envía
if ($status === '') {
    if (in_array($type, ['meeting','task'], true) && $scheduled_at !== '') {
        $status = 'pending';
    } else {
        $status = 'completed';
    }
}

// Forzar comentario estándar en actividades de reunión
if ($type === 'meeting') {
    try {
        if ($scheduled_at !== '') {
            $dt = new DateTime($scheduled_at);
            $description = 'Cita agendada para ' . $dt->format('d/m/Y') . ' a las ' . $dt->format('H:i');
        } else {
            $description = 'Cita agendada';
        }
    } catch (Exception $e) {
        $description = 'Cita agendada';
    }
}

// Validación de solapamiento para reuniones
if ($type === 'meeting' && $scheduled_at !== '') {
    try {
        $userId = intval($_SESSION['user_id'] ?? 0);
        $scope = strtolower(getenv('APPT_BLOCK_SCOPE') ?: 'user'); // 'user' | 'desk'
        // Obtener usuarios del mismo desk si el alcance es 'desk'
        $deskUserIds = [];
        if ($scope === 'desk' && $userId > 0) {
            try {
                $rows = $db->select("SELECT du2.user_id AS uid
                                      FROM desk_users du
                                      INNER JOIN desk_users du2 ON du2.desk_id = du.desk_id
                                      WHERE du.user_id = ?", [$userId]);
                foreach ($rows as $r) { $deskUserIds[] = intval($r['uid']); }
            } catch (Exception $e) { $deskUserIds = []; }
        }
        $startDt = new DateTime($scheduled_at);
        // Fin propuesto según duración enviada
        $endDt = (clone $startDt);
        $endDt->modify('+' . max(1, $duration_min) . ' minutes');
        // Considerar duración por defecto para reuniones existentes (60 min)
        $existingDefaultMin = 60;
        $windowStart = (clone $startDt);
        $windowStart->modify('-' . $existingDefaultMin . ' minutes');

        // Buscar reuniones que comiencen dentro de la ventana [start-DEFAULT, end]
        if ($scope === 'desk' && !empty($deskUserIds)) {
            $placeholders = implode(',', array_fill(0, count($deskUserIds), '?'));
            $params = array_merge($deskUserIds, [$windowStart->format('Y-m-d H:i:s'), $endDt->format('Y-m-d H:i:s')]);
            $conflicts = $db->select(
                "SELECT id, lead_id, subject, scheduled_at, created_by FROM lead_activities 
                 WHERE type = 'meeting' AND status <> 'cancelled' AND scheduled_at IS NOT NULL 
                   AND created_by IN ($placeholders) AND scheduled_at BETWEEN ? AND ?",
                $params
            );
        } else {
            $conflicts = $db->select(
                "SELECT id, lead_id, subject, scheduled_at, created_by FROM lead_activities 
                 WHERE type = 'meeting' AND status <> 'cancelled' AND scheduled_at IS NOT NULL 
                   AND created_by = ? AND scheduled_at BETWEEN ? AND ?",
                [$userId, $windowStart->format('Y-m-d H:i:s'), $endDt->format('Y-m-d H:i:s')]
            );
        }

        // También evitar duplicados por mismo lead en la misma hora exacta
        $dupLead = $db->select(
            "SELECT id FROM lead_activities WHERE type='meeting' AND status <> 'cancelled' AND lead_id = ? AND scheduled_at = ? LIMIT 1",
            [$lead_id, $startDt->format('Y-m-d H:i:s')]
        );

        if (!empty($conflicts) || !empty($dupLead)) {
            http_response_code(409);
            // Preparar detalles mínimos del conflicto para feedback
            $confDetail = [];
            foreach ($conflicts as $c) {
                $confDetail[] = [
                    'id' => (int)$c['id'],
                    'lead_id' => (int)$c['lead_id'],
                    'subject' => (string)$c['subject'],
                    'scheduled_at' => (string)$c['scheduled_at'],
                    'created_by' => (int)$c['created_by']
                ];
            }
            // Generar sugerencias inteligentes de horarios alternativos (hasta 3)
            $suggestions = [];
            try {
                // Obtener horario laboral del primer desk del usuario
                $workStart = '09:00:00';
                $workEnd = '18:00:00';
                try {
                    $deskRow = $db->selectOne("SELECT d.working_hours_start, d.working_hours_end
                                                FROM desks d 
                                                INNER JOIN desk_users du ON du.desk_id = d.id 
                                                WHERE du.user_id = ? ORDER BY du.assigned_at DESC LIMIT 1", [$userId]);
                    if ($deskRow) {
                        $workStart = $deskRow['working_hours_start'] ?: $workStart;
                        $workEnd = $deskRow['working_hours_end'] ?: $workEnd;
                    }
                } catch (Exception $e) {}

                $dayStart = new DateTime($startDt->format('Y-m-d') . ' ' . $workStart);
                $dayEnd = new DateTime($startDt->format('Y-m-d') . ' ' . $workEnd);
                // Comenzar a buscar desde el final de la cita propuesta
                $probe = (clone $endDt);
                // Alinear a intervalos de 15 min
                $m = (int)$probe->format('i'); $probe->modify('+' . (15 - ($m % 15)) . ' minutes');

                $checked = 0;
                while (count($suggestions) < 3 && $checked < 40 && $probe < $dayEnd) {
                    $pEnd = (clone $probe); $pEnd->modify('+' . max(1, $duration_min) . ' minutes');
                    // Ventana de conflicto para candidato
                    $pWinStart = (clone $probe); $pWinStart->modify('-' . $existingDefaultMin . ' minutes');
                    // Consultar conflictos para candidato
                    if ($scope === 'desk' && !empty($deskUserIds)) {
                        $placeholders2 = implode(',', array_fill(0, count($deskUserIds), '?'));
                        $params2 = array_merge($deskUserIds, [$pWinStart->format('Y-m-d H:i:s'), $pEnd->format('Y-m-d H:i:s')]);
                        $rows2 = $db->select(
                            "SELECT id FROM lead_activities WHERE type='meeting' AND status <> 'cancelled' AND scheduled_at IS NOT NULL 
                               AND created_by IN ($placeholders2) AND scheduled_at BETWEEN ? AND ?",
                            $params2
                        );
                        if (empty($rows2)) { $suggestions[] = $probe->format('Y-m-d H:i:s'); }
                    } else {
                        $rows2 = $db->select(
                            "SELECT id FROM lead_activities WHERE type='meeting' AND status <> 'cancelled' AND scheduled_at IS NOT NULL 
                               AND created_by = ? AND scheduled_at BETWEEN ? AND ?",
                            [$userId, $pWinStart->format('Y-m-d H:i:s'), $pEnd->format('Y-m-d H:i:s')]
                        );
                        if (empty($rows2)) { $suggestions[] = $probe->format('Y-m-d H:i:s'); }
                    }
                    $probe->modify('+15 minutes');
                    $checked++;
                }
            } catch (Exception $e) {}

            echo json_encode([
                'ok' => false,
                'error' => 'Conflicto de agenda: ya existe una cita en ese horario',
                'conflicts' => $confDetail,
                'suggestions' => $suggestions
            ]);
            exit;
        }
    } catch (Exception $e) {
        // Si la fecha es inválida, devolver error de validación
        http_response_code(400);
        echo json_encode(['ok' => false, 'error' => 'Fecha/hora de la cita inválida']);
        exit;
    }
}

try {
    // Insertar actividad
    $sql = "INSERT INTO lead_activities (lead_id, type, subject, description, status, scheduled_at, duration_min, created_by, created_at)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())";
    $db->execute($sql, [
        $lead_id,
        $type,
        $subject,
        $description,
        $status,
        ($scheduled_at !== '' ? $scheduled_at : null),
        $duration_min,
        $_SESSION['user_id']
    ]);

    // Actualizaciones en leads
    $updates = [
        'updated_at = NOW()',
        'last_seen = NOW()'
    ];
    $params = [$lead_id];

    // Si es nota, actualizar cache de última nota
    if ($type === 'note') {
        $db->execute("UPDATE leads SET last_note = ?, last_note_at = NOW(), updated_at = NOW(), last_seen = NOW() WHERE id = ?", [$description, $lead_id]);
    } else {
        $db->execute("UPDATE leads SET updated_at = NOW(), last_seen = NOW() WHERE id = ?", [$lead_id]);
    }

    // Datos para respuesta
    $user = $db->selectOne('SELECT username, CONCAT(first_name, " ", last_name) AS name FROM users WHERE id = ?', [$_SESSION['user_id']]);
    $nowRow = $db->selectOne('SELECT NOW() AS now');

    echo json_encode([
        'ok' => true,
        'message' => 'Actividad registrada',
        'activity' => [
            'created_at' => $nowRow['now'] ?? date('Y-m-d H:i:s'),
            'type' => $type,
            'subject' => $subject,
            'description' => $description,
            'status' => $status,
            'scheduled_at' => $scheduled_at ?: null,
            'creator_username' => $user['username'] ?? '',
            'creator_name' => $user['name'] ?? ''
        ]
    ]);
} catch (Exception $e) {
    http_response_code(500);
    echo json_encode(['ok' => false, 'error' => 'Error al registrar la actividad', 'detail' => $e->getMessage()]);
}
?>