<?php
/**
 * ASISMA CRM - Panel visual de Rotacion de Leads (solo matriz)
 *
 * - La rueda: franquiciados por segmento (region + vertical) ordenables por
 *   arrastre (define la prioridad de la cascada) y los vendedores de cada
 *   franquicia ordenables dentro de su cola.
 * - En vivo: leads rotando ahora (con su reloj), huerfanos esperando al cron
 *   y el recorrido de las ultimas rotaciones.
 */
class RotacionController extends Controller {

    private function soloMatriz() {
        if (!SessionHelper::isAdmin()) {
            $this->redirect('dashboard');
        }
    }

    private function soloMatrizJson() {
        if (!SessionHelper::isAdmin()) {
            $this->json(array('success' => false, 'message' => 'Solo la matriz puede usar el panel de rotación.'), 403);
        }
    }

    public function index() {
        $this->soloMatriz();
        $db = Database::getInstance();

        // Lo primero es la VERTICAL: se elige una y dentro de ella se ordena
        // la cascada (los segmentos son las regiones de esa vertical)
        $verticales = $db->fetchAll(
            "SELECT v.id, v.nombre, COUNT(f.id) AS total_franquiciados
             FROM verticales v
             INNER JOIN franquiciados f ON f.vertical_id = v.id
             WHERE v.activa = 1
             GROUP BY v.id, v.nombre
             ORDER BY v.nombre ASC"
        );

        $verticalId = (int)$this->input('vertical_id');
        $idsValidos = array();
        foreach ($verticales as $v) $idsValidos[] = (int)$v['id'];
        if (!in_array($verticalId, $idsValidos)) {
            $verticalId = !empty($idsValidos) ? $idsValidos[0] : 0;
        }

        // Segundo nivel: la MARCA (los leads rotan por vertical Y por marca).
        // Con una marca elegida, la rueda muestra SOLO a quienes pueden atender
        // sus leads: marca completa (genericos y por producto) o productos
        // sueltos de esa marca (solo leads por producto).
        $marcas = $verticalId ? $db->fetchAll(
            "SELECT id, nombre FROM marcas WHERE vertical_id = :vid AND activa = 1 ORDER BY nombre ASC",
            array('vid' => $verticalId)
        ) : array();
        $marcaId = (int)$this->input('marca_id');
        $idsMarcas = array();
        foreach ($marcas as $mk) $idsMarcas[] = (int)$mk['id'];
        if (!in_array($marcaId, $idsMarcas)) $marcaId = 0; // 0 = todas las marcas

        $segmentos = array();
        if ($verticalId) {
            $franquiciados = $db->fetchAll(
                "SELECT f.id, f.prioridad, f.tiempo_toma_lead, f.estado, f.region_id, f.vertical_id,
                        ef.nombre_fantasia, r.nombre AS region_nombre, v.nombre AS vertical_nombre
                 FROM franquiciados f
                 INNER JOIN empresas_franquiciados ef ON ef.id = f.empresa_madre_id
                 INNER JOIN regiones r ON r.id = f.region_id
                 INNER JOIN verticales v ON v.id = f.vertical_id
                 WHERE f.vertical_id = :vid
                 ORDER BY r.nombre ASC, f.prioridad DESC, f.id ASC",
                array('vid' => $verticalId)
            );

            foreach ($franquiciados as $f) {
                $f['marca_completa']  = null;
                $f['sueltos_marca']   = array();
                if ($marcaId) {
                    $completa = $db->fetchOne(
                        "SELECT 1 AS ok FROM franquiciado_marcas WHERE franquiciado_id = :fid AND marca_id = :mid",
                        array('fid' => (int)$f['id'], 'mid' => $marcaId)
                    );
                    $f['marca_completa'] = (bool)$completa;
                    if (!$completa) {
                        $sueltos = $db->fetchAll(
                            "SELECT p.nombre FROM franquiciado_productos fp
                             INNER JOIN productos p ON p.id = fp.producto_id
                             WHERE fp.franquiciado_id = :fid AND p.marca_id = :mid AND p.activo = 1
                             ORDER BY p.nombre ASC",
                            array('fid' => (int)$f['id'], 'mid' => $marcaId)
                        );
                        foreach ($sueltos as $s) $f['sueltos_marca'][] = $s['nombre'];
                        // No vende nada de esta marca: fuera de esta rueda
                        if (empty($f['sueltos_marca'])) continue;
                    }
                }

                $clave = $f['region_id'];
                if (!isset($segmentos[$clave])) {
                    $segmentos[$clave] = array(
                        'region'        => $f['region_nombre'],
                        'vertical'      => $f['vertical_nombre'],
                        'franquiciados' => array()
                    );
                }
                $f['vendedores'] = $db->fetchAll(
                    "SELECT c.usuario_id, c.orden, u.nombre, u.activo
                     FROM cola_asignacion c
                     INNER JOIN usuarios u ON u.id = c.usuario_id
                     WHERE c.franquiciado_id = :fid AND c.activo = 1
                     ORDER BY c.orden ASC",
                    array('fid' => (int)$f['id'])
                );
                $segmentos[$clave]['franquiciados'][] = $f;
            }
        }

        $this->render('rotacion/index', array(
            'title'      => 'Rotación de Leads',
            'verticales' => $verticales,
            'verticalId' => $verticalId,
            'marcas'     => $marcas,
            'marcaId'    => $marcaId,
            'segmentos'  => $segmentos
        ));
    }

    /** JSON en vivo para el panel: rotando ahora, huerfanos, recientes y cron.
     *  Todo filtrado por la vertical elegida (vertical_id; 0 = todas). */
    public function datos() {
        $this->soloMatrizJson();
        $db = Database::getInstance();

        $verticalId     = (int)$this->input('vertical_id');
        $marcaId        = (int)$this->input('marca_id');
        $filtroVertical = $verticalId ? " AND l.vertical_interes = " . $verticalId : "";
        if ($marcaId) $filtroVertical .= " AND l.marca_interes = " . $marcaId;

        // Leads rotando AHORA: asignacion pendiente con su reloj corriendo,
        // incluyendo A QUIEN se le esta notificando (franquicia + vendedor)
        $rotando = $db->fetchAll(
            "SELECT l.id AS lead_id, e.nombre_fantasia AS empresa,
                    COALESCE(p.nombre, mk.nombre, 'Sin producto') AS interes,
                    r.nombre AS region, al.timeout_segundos,
                    al.franquiciado_id, al.usuario_id,
                    ef.nombre_fantasia AS franquicia_notificada, u.nombre AS vendedor_notificado,
                    TIMESTAMPDIFF(SECOND, NOW(), DATE_ADD(al.asignado_at, INTERVAL al.timeout_segundos SECOND)) AS segundos_restantes
             FROM asignaciones_lead al
             INNER JOIN leads l ON l.id = al.lead_id
             LEFT JOIN franquiciados f ON f.id = al.franquiciado_id
             LEFT JOIN empresas_franquiciados ef ON ef.id = f.empresa_madre_id
             LEFT JOIN usuarios u ON u.id = al.usuario_id
             LEFT JOIN empresas e ON e.id = l.empresa_id
             LEFT JOIN productos p ON p.id = l.producto_interes
             LEFT JOIN marcas mk ON mk.id = l.marca_interes
             LEFT JOIN regiones r ON r.id = l.region_id
             WHERE al.estado = 'pendiente' AND l.activo = 1
               AND l.estado_embudo NOT IN ('ganado', 'perdido', 'invalido'){$filtroVertical}
             ORDER BY al.asignado_at ASC"
        );

        // Huerfanos: leads nuevos sin asignacion pendiente, esperando al cron
        $huerfanos = $db->fetchAll(
            "SELECT l.id AS lead_id, e.nombre_fantasia AS empresa,
                    COALESCE(p.nombre, mk.nombre, 'Sin producto') AS interes,
                    r.nombre AS region, v.nombre AS vertical,
                    TIMESTAMPDIFF(MINUTE, l.created_at, NOW()) AS minutos_esperando
             FROM leads l
             LEFT JOIN empresas e ON e.id = l.empresa_id
             LEFT JOIN productos p ON p.id = l.producto_interes
             LEFT JOIN marcas mk ON mk.id = l.marca_interes
             LEFT JOIN regiones r ON r.id = l.region_id
             LEFT JOIN verticales v ON v.id = l.vertical_interes
             WHERE l.estado_embudo = 'nuevo' AND l.activo = 1
               AND NOT EXISTS (SELECT 1 FROM asignaciones_lead al
                               WHERE al.lead_id = l.id AND al.estado = 'pendiente'){$filtroVertical}
             ORDER BY l.created_at ASC"
        );

        // Ultimos leads con movimiento de rotacion
        $recientes = $db->fetchAll(
            "SELECT l.id AS lead_id, e.nombre_fantasia AS empresa, l.estado_embudo,
                    COALESCE(p.nombre, mk.nombre, 'Sin producto') AS interes,
                    MAX(al.id) AS ultima
             FROM asignaciones_lead al
             INNER JOIN leads l ON l.id = al.lead_id
             LEFT JOIN empresas e ON e.id = l.empresa_id
             LEFT JOIN productos p ON p.id = l.producto_interes
             LEFT JOIN marcas mk ON mk.id = l.marca_interes
             WHERE 1=1{$filtroVertical}
             GROUP BY l.id, e.nombre_fantasia, l.estado_embudo, p.nombre, mk.nombre
             ORDER BY ultima DESC
             LIMIT 8"
        );

        // Recorrido (journey) de todos los leads involucrados
        $idsLeads = array();
        foreach ($rotando as $fila)   $idsLeads[] = (int)$fila['lead_id'];
        foreach ($recientes as $fila) $idsLeads[] = (int)$fila['lead_id'];
        $idsLeads = array_unique($idsLeads);

        $recorridos = array();
        if (!empty($idsLeads)) {
            $filas = $db->fetchAll(
                "SELECT al.lead_id, al.estado, ef.nombre_fantasia AS franquicia, u.nombre AS vendedor
                 FROM asignaciones_lead al
                 INNER JOIN franquiciados f ON f.id = al.franquiciado_id
                 INNER JOIN empresas_franquiciados ef ON ef.id = f.empresa_madre_id
                 LEFT JOIN usuarios u ON u.id = al.usuario_id
                 WHERE al.lead_id IN (" . implode(',', $idsLeads) . ")
                 ORDER BY al.id ASC"
            );
            foreach ($filas as $fila) {
                $recorridos[(int)$fila['lead_id']][] = array(
                    'franquicia' => $fila['franquicia'],
                    'vendedor'   => $fila['vendedor'],
                    'estado'     => $fila['estado']
                );
            }
        }

        // Estado del cron segun su log
        $rutaLog = LOG_DIR . '/rotacion_leads.log';
        $cron = array('activo' => false, 'ultima_corrida' => null, 'hace_segundos' => null, 'ultima_linea' => '');
        if (file_exists($rutaLog)) {
            $modificado = filemtime($rutaLog);
            $cron['ultima_corrida'] = date('d-m-Y H:i:s', $modificado);
            $cron['hace_segundos']  = time() - $modificado;
            $cron['activo']         = $cron['hace_segundos'] < 180; // corrio en los ultimos 3 min
            $lineas = file($rutaLog, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
            if ($lineas) $cron['ultima_linea'] = end($lineas);
        }

        $this->json(array(
            'success'    => true,
            'rotando'    => $rotando,
            'huerfanos'  => $huerfanos,
            'recientes'  => $recientes,
            'recorridos' => $recorridos,
            'cron'       => $cron
        ));
    }

    /**
     * POST: nuevo orden de la cascada de un segmento. Recibe franquiciados[]
     * (ids en el orden deseado) y asigna prioridades descendentes.
     */
    public function ordenarFranquiciados() {
        $this->soloMatrizJson();
        $orden = isset($_POST['franquiciados']) && is_array($_POST['franquiciados'])
            ? array_map('intval', $_POST['franquiciados']) : array();
        if (empty($orden)) {
            $this->json(array('success' => false, 'message' => 'No llegó el orden de los franquiciados.'));
        }

        $db = Database::getInstance();
        $total = count($orden);
        foreach ($orden as $indice => $fid) {
            if ($fid <= 0) continue;
            // Mayor prioridad = primero en la cascada
            $db->update('franquiciados', array('prioridad' => ($total - $indice) * 10), 'id = :id', array(':id' => $fid));
        }
        AuditHelper::log('ordenar_cascada', 'franquiciados', null, null, array('orden' => $orden));
        $this->json(array('success' => true, 'message' => 'Orden de la cascada actualizado.'));
    }

    /**
     * POST: nuevo orden de los vendedores en la cola de una franquicia.
     * Recibe franquiciado_id y usuarios[] (ids en el orden deseado).
     */
    public function ordenarCola() {
        $this->soloMatrizJson();
        $franquiciadoId = (int)$this->input('franquiciado_id');
        $orden = isset($_POST['usuarios']) && is_array($_POST['usuarios'])
            ? array_map('intval', $_POST['usuarios']) : array();
        if ($franquiciadoId <= 0 || empty($orden)) {
            $this->json(array('success' => false, 'message' => 'Datos incompletos para ordenar la cola.'));
        }

        $db = Database::getInstance();
        foreach ($orden as $indice => $uid) {
            if ($uid <= 0) continue;
            $db->update('cola_asignacion', array('orden' => $indice + 1),
                'franquiciado_id = :fid AND usuario_id = :uid',
                array(':fid' => $franquiciadoId, ':uid' => $uid));
        }
        AuditHelper::log('ordenar_cola', 'cola_asignacion', $franquiciadoId, null, array('orden' => $orden));
        $this->json(array('success' => true, 'message' => 'Orden de la cola actualizado.'));
    }
}
