403Webshell
Server IP : 127.0.0.1  /  Your IP : 216.73.216.109
Web Server : Apache/2.4.54 (Win64) OpenSSL/1.1.1q PHP/8.1.10
System : Windows NT DESKTOP-E5T4RUN 10.0 build 19045 (Windows 10) AMD64
User : SERVERWEB ( 0)
PHP Version : 8.1.10
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : OFF |  Perl : OFF |  Python : OFF |  Sudo : OFF |  Pkexec : OFF
Directory :  C:/laragon/www/modules/e-gamq/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : C:/laragon/www/modules/e-gamq/chatbot.js
function initializeChatbot() {
    const chatbotContainer = document.getElementById('chatbot-container');
    const chatbotToggle = document.getElementById('chatbot-toggle');
    const chatbotClose = document.getElementById('chatbot-close');
    const chatbotMessages = document.getElementById('chatbot-messages');
    const chatbotOptions = document.getElementById('chatbot-options');
    const chatbotInput = document.getElementById('chatbot-input');
    const chatbotSend = document.getElementById('chatbot-send');
    if (!chatbotContainer || !chatbotToggle || !chatbotClose || !chatbotMessages || !chatbotOptions || !chatbotInput || !chatbotSend) {
        return;
    }
    if (chatbotContainer.dataset.initialized === 'true') {
        return;
    }
    chatbotContainer.dataset.initialized = 'true';

    let navigationStack = ['main'];
    let isInitialized = false;
    let hasUserAskedQuestion = false;
    const siteRootUrl = getSiteRootUrl();
    const knowledgeCache = {
        systems: null,
        news: null,
        pages: {}
    };
    const unitPages = [
        { id: 'agricola', name: 'Agrícola', url: 'modules/unidades/index-Agricola.html', keywords: ['agricola', 'agrícola', 'agricultura'] },
        { id: 'cultura', name: 'Cultura', url: 'modules/unidades/index-Cultura.html', keywords: ['cultura', 'cultural'] },
        { id: 'educacion', name: 'Educación', url: 'modules/unidades/index-Educacion.html', keywords: ['educacion', 'educación', 'colegio', 'escuela'] },
        { id: 'turismo', name: 'Turismo', url: 'modules/unidades/index-Turismo.html', keywords: ['turismo', 'turistica', 'turística'] },
        { id: 'zoonosis', name: 'Zoonosis', url: 'modules/unidades/index-Zoonosis.html', keywords: ['zoonosis', 'vacunacion', 'vacunación', 'esterilizacion', 'esterilización', 'animal'] },
        { id: 'pecuaria', name: 'Pecuaria', url: 'modules/unidades/index-Pecuaria.html', keywords: ['pecuaria', 'ganado'] },
        { id: 'riegos', name: 'Riegos', url: 'modules/unidades/index-Riegos.html', keywords: ['riegos', 'riego', 'agua'] },
        { id: 'red-monica', name: 'Red Mónica', url: 'modules/unidades/index-Red-Monica.html', keywords: ['red monica', 'red mónica', 'monica', 'mónica', 'aire'] },
        { id: 'preservacion-ambiental', name: 'Preservación Ambiental', url: 'modules/unidades/index-Preservacion-ambiental.html', keywords: ['preservacion', 'preservación', 'ambiental', 'medio ambiente'] },
        { id: 'recursos-naturales', name: 'Recursos Naturales', url: 'modules/unidades/index-Recursos-naturales.html', keywords: ['recursos naturales', 'naturales'] },
        { id: 'parques-jardines', name: 'Parques y Jardines', url: 'modules/unidades/index-Parques-jardines.html', keywords: ['parques', 'jardines', 'parques y jardines'] },
        { id: 'forestal', name: 'Forestal', url: 'modules/unidades/index-Forestal.html', keywords: ['forestal', 'arboles', 'árboles'] },
        { id: 'tdi', name: 'TDI - Sistemas', url: 'modules/unidades/index-TDI.html', keywords: ['tdi', 'sistemas', 'tecnologia', 'tecnología'] },
        { id: 'ugr', name: 'UGR', url: 'modules/unidades/index-UGR.html', keywords: ['ugr', 'riesgos', 'emergencia'] },
        { id: 'dio', name: 'DIO', url: 'modules/unidades/index-DIO.html', keywords: ['dio', 'defensoria', 'defensoría'] }
    ];

    function getSiteRootUrl() {
        const pathname = window.location.pathname;
        const unidadesIndex = pathname.toLowerCase().indexOf('/modules/unidades/');
        if (unidadesIndex !== -1) {
            return `${window.location.origin}${pathname.slice(0, unidadesIndex + 1)}`;
        }

        return new URL('./', window.location.href).href;
    }

    function siteUrl(path) {
        if (/^https?:\/\//i.test(path)) {
            return path;
        }
        return new URL(path.replace(/^\/+/, ''), siteRootUrl).href;
    }

    function normalizeText(value) {
        return String(value || '')
            .normalize('NFD')
            .replace(/[\u0300-\u036f]/g, '')
            .toLowerCase()
            .replace(/\s+/g, ' ')
            .trim();
    }

    function cleanText(value) {
        return String(value || '').replace(/\s+/g, ' ').trim();
    }

    function escapeHtml(value) {
        const div = document.createElement('div');
        div.textContent = value || '';
        return div.innerHTML;
    }

    function addBotHtml(html) {
        const messageDiv = document.createElement('div');
        messageDiv.className = 'chatbot-message bot-message';
        const shouldCollapse = html.length > 900 || (html.match(/<br>/g) || []).length > 10;
        messageDiv.innerHTML = `
            <div class="chatbot-rich-content ${shouldCollapse ? 'is-collapsed' : ''}">${html}</div>
            ${shouldCollapse ? '<button class="chatbot-read-more" type="button">Ver más</button>' : ''}
        `;
        chatbotMessages.appendChild(messageDiv);
        const readMore = messageDiv.querySelector('.chatbot-read-more');
        if (readMore) {
            readMore.addEventListener('click', function() {
                const content = messageDiv.querySelector('.chatbot-rich-content');
                content.classList.toggle('is-collapsed');
                readMore.textContent = content.classList.contains('is-collapsed') ? 'Ver más' : 'Ver menos';
                chatbotMessages.scrollTop = chatbotMessages.scrollHeight;
            });
        }
        chatbotMessages.scrollTop = chatbotMessages.scrollHeight;
    }

    function renderOptions(html, mode = 'panel') {
        chatbotOptions.dataset.mode = mode;
        chatbotOptions.innerHTML = html;
    }

    function minimizeOptions() {
        chatbotOptions.dataset.mode = 'minimized';
        chatbotOptions.innerHTML = '<button class="chatbot-topic-toggle" type="button">Ver otros temas</button>';
        const toggle = chatbotOptions.querySelector('.chatbot-topic-toggle');
        if (toggle) {
            toggle.addEventListener('click', showMainOptions);
        }
    }

    function getQueryTokens(message) {
        const stopWords = new Set(['que', 'cual', 'cuales', 'como', 'donde', 'para', 'sobre', 'tiene', 'hay', 'los', 'las', 'del', 'una', 'uno', 'con', 'por', 'ese', 'esa', 'este', 'esta', 'sistema', 'sistemas', 'unidad', 'unidades']);
        return normalizeText(message)
            .split(/[^a-z0-9]+/)
            .filter(token => token.length > 2 && !stopWords.has(token));
    }

    function scoreText(text, tokens) {
        const normalized = normalizeText(text);
        return tokens.reduce((score, token) => score + (normalized.includes(token) ? 1 : 0), 0);
    }

    function isContactIntent(message) {
        return normalizeText(message).match(/\b(contacto|contactos|telefono|telefonos|celular|whatsapp|correo|email|llamar|contactar)\b/);
    }

    function isAddressIntent(message) {
        return normalizeText(message).match(/\b(direccion|direcciones|ubicacion|ubicaciones|oficina|oficinas|donde queda|donde estan|mapa)\b/);
    }

    function isNewsIntent(message) {
        return normalizeText(message).match(/\b(noticia|noticias|anuncio|anuncios|comunicado|comunicados|novedad|novedades|actualidad|ultimo|ultimos|ultima|ultimas|reciente|recientes)\b/);
    }

    async function loadHtmlDocument(pathOrUrl) {
        const absoluteUrl = /^https?:\/\//i.test(pathOrUrl) ? pathOrUrl : siteUrl(pathOrUrl);
        const response = await fetch(absoluteUrl, { cache: 'no-store' });
        if (!response.ok) {
            throw new Error(`HTTP ${response.status}`);
        }
        const html = await response.text();
        return {
            url: absoluteUrl,
            doc: new DOMParser().parseFromString(html, 'text/html')
        };
    }

    function resolvePageUrl(basePathOrUrl, href) {
        return new URL(href, /^https?:\/\//i.test(basePathOrUrl) ? basePathOrUrl : siteUrl(basePathOrUrl)).href;
    }

    function extractRelevantLines(doc, keywords = []) {
        const normalizedKeywords = keywords.map(normalizeText);
        return Array.from(doc.querySelectorAll('h1, h2, h3, h4, h5, p, li, .desc, .column_attr'))
            .map(element => cleanText(element.textContent))
            .filter(text => {
                if (text.length < 4 || /lorem ipsum|your name|your e-mail|subject|message/i.test(text)) {
                    return false;
                }
                const normalized = normalizeText(text);
                const hasContactData = /(\+?\(?591\)?|[67]\d{7}|\b\d{7,}\b|@|direccion|dirección|ubicacion|ubicación|oficina|celular|telefono|teléfono|whatsapp|plaza)/i.test(text);
                return hasContactData || normalizedKeywords.some(keyword => normalized.includes(keyword));
            })
            .filter((text, index, lines) => lines.indexOf(text) === index)
            .slice(0, 8);
    }

    async function loadGovernmentSystems() {
        if (knowledgeCache.systems) {
            return knowledgeCache.systems;
        }

        try {
            const response = await fetch(siteUrl('sections/section-apps.php'), { cache: 'no-store' });
            if (!response.ok) {
                throw new Error(`HTTP ${response.status}`);
            }
            const html = await response.text();
            const doc = new DOMParser().parseFromString(html, 'text/html');
            const cards = Array.from(doc.querySelectorAll('.app-card'));
            knowledgeCache.systems = cards.map(card => ({
                name: cleanText(card.querySelector('.app-title')?.textContent),
                description: cleanText(card.querySelector('.app-description')?.textContent),
                status: cleanText(card.querySelector('.app-status')?.textContent),
                url: card.dataset.url || '',
                categories: card.dataset.category || ''
            })).filter(system => system.name);
        } catch (error) {
            console.warn('No se pudo cargar la lista de sistemas:', error);
            knowledgeCache.systems = [];
        }

        return knowledgeCache.systems;
    }

    async function loadPageSummary(path) {
        const absoluteUrl = siteUrl(path);
        if (knowledgeCache.pages[absoluteUrl]) {
            return knowledgeCache.pages[absoluteUrl];
        }

        const { doc } = await loadHtmlDocument(absoluteUrl);
        doc.querySelectorAll('script, style, nav, footer, header, #chatbot-container, #chatbot-toggle').forEach(element => element.remove());
        const title = cleanText(doc.querySelector('h1, h2, title')?.textContent);
        const fragments = Array.from(doc.querySelectorAll('h1, h2, h3, h4, h5, p, li'))
            .map(element => cleanText(element.textContent))
            .filter(text => text.length > 35 && !/lorem ipsum/i.test(text))
            .slice(0, 8);
        const summary = {
            title,
            text: fragments.join(' '),
            url: absoluteUrl
        };
        knowledgeCache.pages[absoluteUrl] = summary;
        return summary;
    }

    function findRequestedUnit(message) {
        const normalizedMessage = normalizeText(message);
        return unitPages.find(unit => unit.keywords.some(keyword => normalizedMessage.includes(normalizeText(keyword))));
    }

    async function loadUnitContactInfo(unit, message) {
        const wantsAddress = isAddressIntent(message);
        const { doc: unitDoc } = await loadHtmlDocument(unit.url);
        const contactLink = Array.from(unitDoc.querySelectorAll('a[href]'))
            .map(anchor => ({
                href: anchor.getAttribute('href'),
                text: cleanText(anchor.textContent)
            }))
            .find(link => normalizeText(`${link.text} ${link.href}`).match(/\b(contacto|contactos|contact|contacts|contact-us|contactanos|contáctanos|contact-and-help)\b/));

        let sourceUrl = siteUrl(unit.url);
        let sourceDoc = unitDoc;
        if (contactLink && contactLink.href && !contactLink.href.startsWith('#')) {
            sourceUrl = resolvePageUrl(unit.url, contactLink.href);
            sourceDoc = (await loadHtmlDocument(sourceUrl)).doc;
        }

        sourceDoc.querySelectorAll('script, style, nav, footer, header, form, #chatbot-container, #chatbot-toggle').forEach(element => element.remove());
        const lines = extractRelevantLines(sourceDoc, wantsAddress ? ['direccion', 'ubicacion', 'oficina'] : ['contacto', 'celular', 'telefono', 'correo']);
        return {
            lines,
            url: sourceUrl
        };
    }

    async function answerUnitContactQuestion(message) {
        const unit = findRequestedUnit(message);
        if (!unit || (!isContactIntent(message) && !isAddressIntent(message))) {
            return false;
        }

        try {
            const contact = await loadUnitContactInfo(unit, message);
            if (contact.lines.length) {
                addBotHtml(`<strong>${escapeHtml(isAddressIntent(message) ? `Dirección / ubicación de ${unit.name}` : `Contactos de ${unit.name}`)}</strong><br>${contact.lines.map(line => `• ${escapeHtml(line)}`).join('<br>')}<br><a href="${escapeHtml(contact.url)}">Ver página de contacto</a>`);
            } else {
                addBotHtml(`No encontré datos específicos de contacto para ${escapeHtml(unit.name)} en su página, pero puedes revisar aquí:<br><a href="${escapeHtml(contact.url)}">Ver página de ${escapeHtml(unit.name)}</a>`);
            }
        } catch (error) {
            addBotHtml(`No pude leer los contactos actualizados de ${escapeHtml(unit.name)} en este momento. Puedes abrir su página aquí:<br><a href="${escapeHtml(siteUrl(unit.url))}">Ver página de ${escapeHtml(unit.name)}</a>`);
        }
        return true;
    }

    async function answerGeneralContactQuestion(message) {
        if (!isContactIntent(message) && !isAddressIntent(message)) {
            return false;
        }

        try {
            const { doc, url } = await loadHtmlDocument('pages/contact.html');
            doc.querySelectorAll('script, style, nav, footer, header, form').forEach(element => element.remove());
            const lines = extractRelevantLines(doc, ['direccion', 'contacto', 'telefono', 'correo', 'email', 'oficina']);
            if (!lines.length) {
                return false;
            }
            addBotHtml(`<strong>Contactos del GAMQ</strong><br>${lines.map(line => `• ${escapeHtml(line)}`).join('<br>')}<br><a href="${escapeHtml(url)}">Ver página de contacto</a>`);
            return true;
        } catch (error) {
            addBotHtml(`Puedes ver los contactos del GAMQ aquí:<br><a href="${escapeHtml(siteUrl('pages/contact.html'))}">Página de contacto</a>`);
            return true;
        }
    }

    async function loadLatestNews() {
        if (knowledgeCache.news) {
            return knowledgeCache.news;
        }

        try {
            const { doc } = await loadHtmlDocument('sections/section-news.php');
            knowledgeCache.news = Array.from(doc.querySelectorAll('.post-item')).map(item => ({
                title: cleanText(item.querySelector('.entry-title a, h3 a, h3')?.textContent),
                date: cleanText(item.querySelector('.date, .date_label')?.textContent),
                category: cleanText(item.querySelector('.post-categories a')?.textContent),
                url: item.querySelector('.entry-title a, h3 a, .image_links a')?.getAttribute('href') || ''
            })).filter(news => news.title).slice(0, 5);
        } catch (error) {
            console.warn('No se pudieron cargar las últimas noticias:', error);
            knowledgeCache.news = [];
        }

        return knowledgeCache.news;
    }

    async function answerNewsQuestion(message) {
        if (!isNewsIntent(message)) {
            return false;
        }

        const news = await loadLatestNews();
        if (!news.length) {
            addBotHtml(`No pude cargar las noticias actualizadas en este momento. Puedes revisarlas aquí:<br><a href="${escapeHtml(siteUrl('pages/news.html'))}">Ver noticias</a>`);
            return true;
        }

        const rows = news.map(item => {
            const link = item.url ? ` - <a href="${escapeHtml(item.url)}" target="_blank" rel="noopener">ver</a>` : '';
            const meta = [item.date, item.category].filter(Boolean).join(' · ');
            return `• <strong>${escapeHtml(item.title)}</strong>${meta ? `<br><small>${escapeHtml(meta)}</small>` : ''}${link}`;
        }).join('<br>');
        addBotHtml(`<strong>Últimas noticias y anuncios</strong><br>${rows}<br><a href="${escapeHtml(siteUrl('pages/news.html'))}">Ver todas las noticias</a>`);
        return true;
    }

    async function answerGovernmentSystemsQuestion(message) {
        const systems = await loadGovernmentSystems();
        if (!systems.length) {
            return false;
        }

        const tokens = getQueryTokens(message);
        const wantsList = normalizeText(message).match(/\b(lista|listar|sistemas|aplicaciones|apps|gobierno electronico|gobierno electrónico)\b/);
        const matches = systems
            .map(system => ({
                system,
                score: scoreText(`${system.name} ${system.description} ${system.categories}`, tokens)
            }))
            .filter(item => item.score > 0)
            .sort((a, b) => b.score - a.score);

        if (!wantsList && matches.length === 0) {
            return false;
        }

        if (matches.length === 1 && matches[0].score >= 1 && !wantsList) {
            const system = matches[0].system;
            const link = system.url ? `<br><a href="${escapeHtml(system.url)}" target="_blank" rel="noopener">Abrir ${escapeHtml(system.name)}</a>` : '<br>Este sistema no tiene enlace público registrado.';
            addBotHtml(`<strong>${escapeHtml(system.name)}</strong><br>${escapeHtml(system.description)}<br>Estado: ${escapeHtml(system.status || 'No especificado')}.${link}`);
            return true;
        }

        const list = (matches.length ? matches : systems)
            .slice(0, 8)
            .map(item => item.system || item)
            .map(system => {
                const link = system.url ? ` - <a href="${escapeHtml(system.url)}" target="_blank" rel="noopener">abrir</a>` : '';
                return `• <strong>${escapeHtml(system.name)}</strong>: ${escapeHtml(system.description)}${link}`;
            })
            .join('<br>');

        addBotHtml(`Estos son algunos sistemas de Gobierno Electrónico disponibles:<br>${list}<br><br>También puedes preguntar por uno específico, por ejemplo: ODECO, FISQUI, SIGECEM, Deportes o Trámites.`);
        return true;
    }

    async function answerUnitQuestion(message) {
        const unit = findRequestedUnit(message);
        if (!unit) {
            return false;
        }

        try {
            const summary = await loadPageSummary(unit.url);
            const sentences = summary.text.match(/[^.!?]+[.!?]?/g) || [summary.text];
            const usefulText = sentences.slice(0, 3).join(' ').slice(0, 420);
            addBotHtml(`<strong>${escapeHtml(unit.name)}</strong><br>${escapeHtml(usefulText || 'Tengo registrada esta unidad en el portal del GAMQ.')}<br><a href="${escapeHtml(summary.url)}">Ver página de ${escapeHtml(unit.name)}</a>`);
        } catch (error) {
            addBotHtml(`No pude leer la página actualizada de ${escapeHtml(unit.name)} en este momento, pero puedes abrirla aquí:<br><a href="${escapeHtml(siteUrl(unit.url))}">Ver página de ${escapeHtml(unit.name)}</a>`);
        }
        return true;
    }

    function answerCurrentPageQuestion(message) {
        const normalizedMessage = normalizeText(message);
        if (!normalizedMessage.match(/\b(esta pagina|pagina actual|aqui|este sitio|informacion de esta)\b/)) {
            return false;
        }

        const clone = document.body.cloneNode(true);
        clone.querySelectorAll('script, style, nav, footer, header, #chatbot-container, #chatbot-toggle').forEach(element => element.remove());
        const fragments = Array.from(clone.querySelectorAll('h1, h2, h3, h4, p, li'))
            .map(element => cleanText(element.textContent))
            .filter(text => text.length > 40 && !/lorem ipsum/i.test(text))
            .slice(0, 4);

        if (!fragments.length) {
            return false;
        }

        addBotHtml(`En esta página encontré esta información:<br>${fragments.map(fragment => `• ${escapeHtml(fragment)}`).join('<br>')}`);
        return true;
    }

    async function answerFromKnowledge(message) {
        const normalizedMessage = normalizeText(message);

        if (await answerUnitContactQuestion(message)) {
            return true;
        }

        if (await answerGeneralContactQuestion(message)) {
            return true;
        }

        if (await answerNewsQuestion(message)) {
            return true;
        }

        if (answerCurrentPageQuestion(message)) {
            return true;
        }

        if (await answerUnitQuestion(message)) {
            return true;
        }

        if (normalizedMessage.match(/\b(gobierno electronico|gobierno electrónico|sistema|sistemas|aplicacion|aplicaciones|app|apps|odeco|fisqui|sigecem|parqui|provegaq|presqui|matadero|biblioteca|taskboard|tramites|trámites)\b/)) {
            return answerGovernmentSystemsQuestion(message);
        }

        return false;
    }

    chatbotToggle.addEventListener('click', function() {
        chatbotContainer.style.display = 'flex';
        chatbotToggle.style.display = 'none';
        if (!isInitialized) {
            initializeChat();
            isInitialized = true;
        }
        
        chatbotInput.focus();
    });
    
    chatbotClose.addEventListener('click', function(event) {
        event.preventDefault();
        event.stopPropagation();
        chatbotContainer.style.display = 'none';
        chatbotToggle.style.display = 'flex';
    });
    function initializeChat() {
        chatbotMessages.innerHTML = '';
        addMessage("¡Hola! Soy tu asistente virtual del Gobierno Autónomo Municipal de Quillacollo. Estoy aquí para ayudarte con:", 'bot');
        showMainOptions();
    }
    function sendMessage() {
        const message = chatbotInput.value.trim();
        if (message) {
            hasUserAskedQuestion = true;
            if (chatbotOptions.dataset.mode === 'main') {
                showMainOptions();
            }
            addMessage(message, 'user');
            chatbotInput.value = '';
            setTimeout(() => {
                processUserMessage(message);
            }, 500);
        }
    }    
    chatbotSend.addEventListener('click', sendMessage);    
    chatbotInput.addEventListener('keypress', function(e) {
        if (e.key === 'Enter') {
            sendMessage();
        }
    });
    function addMessage(text, type) {
        const messageDiv = document.createElement('div');
        messageDiv.className = `chatbot-message ${type}-message`;
        messageDiv.innerHTML = `<p>${text}</p>`;
        chatbotMessages.appendChild(messageDiv);
        chatbotMessages.scrollTop = chatbotMessages.scrollHeight;
    }

    async function processUserMessage(message) {
        const lowerMessage = message.toLowerCase();
        
        if (lowerMessage.match(/\b(hola|buenas|buenos dias|buenas tardes|saludos|hey)\b/)) {
            addMessage("¡Hola! ¿En qué puedo ayudarte hoy?", 'bot');
            showMainOptions();
            return;
        }
        
        if (lowerMessage.match(/\b(gracias|agradecido|agradecida|muchas gracias)\b/)) {
            addMessage("¡De nada! Fue un placer ayudarte. Si necesitas algo más, aquí estoy.", 'bot');
            showMainOptions();
            return;
        }
        
        if (lowerMessage.match(/\b(adios|chao|hasta luego|nos vemos)\b/)) {
            addMessage("¡Hasta pronto! Que tengas un excelente día. Estoy aquí cuando me necesites.", 'bot');
            return;
        }

        if (await answerFromKnowledge(message)) {
            return;
        }
        
        if (lowerMessage.match(/\b(unidad|unidades|departamento|sección|área)\b/)) {
            navigationStack.push('unidades');
            showUnidadesOptions();
            return;
        }        
        
        if (lowerMessage.match(/\b(noticia|noticias|novedad|novedades|actualidad)\b/)) {
            redirectToNoticias();
            return;
        }        
        
        if (lowerMessage.match(/\b(quillacollo|municipio|información|info|sobre)\b/)) {
            redirectToInfo();
            return;
        }        
        
        if (lowerMessage.match(/\b(denuncia|reclamo|queja|problema|seguimiento|seguir|estado|progreso|avance|track|tracking)\b/)) {
            navigationStack.push('denuncia-reclamo');
            showDenunciaReclamoOptions();
            return;
        }        
        
        if (lowerMessage.match(/\b(contacto|contactar|equipo|whatsapp|teléfono|llamar)\b/)) {
            redirectToContacto();
            return;
        }
        
        if (lowerMessage.match(/\b(ruat|deuda|deudas|consulta|impuesto|impuestos|vehiculo|vehiculos|inmueble|inmuebles|actividad economica)\b/)) {
            navigationStack.push('consultas');
            showConsultasOptions();
            return;
        }
        
        if (lowerMessage.match(/\b(deporte|deportes|reserva|reservar|cancha|canchas|complejo|complejos|deportivo|deportivos)\b/)) {
            redirectToDeportes();
            return;
        }
        
        if (lowerMessage.match(/\b(seguimiento|seguir|estado|progreso|avance|track|tracking|código|número de caso|referencia)\b/)) {
            navigationStack.push('seguimiento');
            showSeguimientoOptions();
            return;
        }
        
        addMessage("Entiendo que tienes una consulta. Para brindarte mejor asistencia, puedes seleccionar una de las opciones disponibles o escribir sobre:", 'bot');
        addMessage("• Unidades del GAMQ\n• Consulta de deudas (RUAT)\n• Reservas deportivas\n• Noticias y novedades\n• Denuncias o reclamos\n• Seguimiento de casos\n• Contacto", 'bot');
        showMainOptions();
    }
    
    function showMainOptions(forceExpanded = false) {
        navigationStack = ['main'];        
        const isCompact = hasUserAskedQuestion && !forceExpanded;
        const titleText = isCompact ? 'Más opciones' : 'Opciones disponibles';
        const titleAction = isCompact ? 'expand-options' : 'collapse-options';
        const titleLabel = isCompact ? 'Expandir opciones' : 'Contraer opciones';
        const titleIcon = isCompact ? '▲' : '▼';
        const optionsTitleHTML = `
            <div class="chatbot-options-title">
                <div class="chatbot-options-title-text">${titleText}</div>
                ${hasUserAskedQuestion ? `<button class="chatbot-expand-options" type="button" data-action="${titleAction}" aria-label="${titleLabel}">${titleIcon}</button>` : ''}
            </div>
        `;
        const mainOptionsHTML = isCompact ? optionsTitleHTML : `
            ${optionsTitleHTML}
            <div class="quick-options-row">
                <button class="option-button" data-option="contacto">
                    <span class="option-icon">
                        <i class="fab fa-whatsapp"></i>
                    </span>
                    <span class="option-text">Contactar</span>
                </button>
                <button class="option-button" data-option="denuncia-reclamo">
                    <span class="option-icon">⚠️</span>
                    <span class="option-text">Denuncia o Reclamo</span>
                </button>
                <button class="option-button" data-option="consultas">
                    <span class="option-icon">💳</span>
                    <span class="option-text">Deudas RUAT</span>
                </button>
                <button class="option-button" data-option="deportes">
                    <span class="option-icon">⚽</span>
                    <span class="option-text">Reservas Deportivas</span>
                </button>
                <button class="option-button" data-option="quillacollo">
                    <span class="option-icon">ℹ️</span>
                    <span class="option-text">Sobre Quillacollo</span>
                </button>
            </div>
        `;
                // <button class="option-button" data-option="sistemas">
                //     <span class="option-icon">💻</span>
                //     <span class="option-text">Gobierno Electrónico</span>
                // </button>
                // <button class="option-button" data-option="unidades">
                //     <span class="option-icon">📋</span>
                //     <span class="option-text">Unidades</span>
                // </button>
                // <button class="option-button" data-option="noticias">
                //     <span class="option-icon">📰</span>
                //     <span class="option-text">Noticias</span>
                // </button>
        renderOptions(mainOptionsHTML, isCompact ? 'main-compact' : 'main');
        const expandButton = chatbotOptions.querySelector('[data-action="expand-options"]');
        if (expandButton) {
            expandButton.addEventListener('click', function() {
                showMainOptions(true);
            });
        }
        const collapseButton = chatbotOptions.querySelector('[data-action="collapse-options"]');
        if (collapseButton) {
            collapseButton.addEventListener('click', function() {
                showMainOptions(false);
            });
        }
        chatbotOptions.querySelectorAll('.option-button').forEach(button => {
            button.addEventListener('click', function() {
                const option = this.getAttribute('data-option');
                handleOptionSelection(option);
            });
        });
    }

    function showUnidadesOptions() {
        addMessage("Selecciona la unidad sobre la que deseas información:", 'bot');        
        const unidadesHTML = `
            <div class="options-grid">
                <button class="option-button" data-unidad="agricola">
                    <span class="option-icon">🌱</span>
                    <span class="option-text">Agrícola</span>
                </button>
                <button class="option-button" data-unidad="cultura">
                    <span class="option-icon">🎭</span>
                    <span class="option-text">Cultura</span>
                </button>
                <button class="option-button" data-unidad="educacion">
                    <span class="option-icon">🎓</span>
                    <span class="option-text">Educación</span>
                </button>
                <button class="option-button" data-unidad="turismo">
                    <span class="option-icon">🏞️</span>
                    <span class="option-text">Turismo</span>
                </button>
                <button class="option-button" data-unidad="zoonosis">
                    <span class="option-icon">🐾</span>
                    <span class="option-text">Zoonosis</span>
                </button>
                <button class="option-button" data-unidad="pecuaria">
                    <span class="option-icon">🐄</span>
                    <span class="option-text">Pecuaria</span>
                </button>
                <button class="option-button" data-unidad="riegos">
                    <span class="option-icon">💧</span>
                    <span class="option-text">Riegos</span>
                </button>
                <button class="option-button" data-unidad="red-monica">
                    <span class="option-icon">🌬️</span>
                    <span class="option-text">Red Mónica</span>
                </button>
                <button class="option-button" data-unidad="preservacion-ambiental">
                    <span class="option-icon">🌿</span>
                    <span class="option-text">Preservación Ambiental</span>
                </button>
                <button class="option-button" data-unidad="recursos-naturales">
                    <span class="option-icon">🌳</span>
                    <span class="option-text">Recursos Naturales</span>
                </button>
                <button class="option-button" data-unidad="parques-jardines">
                    <span class="option-icon">🌷</span>
                    <span class="option-text">Parques y Jardines</span>
                </button>
                <button class="option-button" data-unidad="forestal">
                    <span class="option-icon">🌲</span>
                    <span class="option-text">Forestal</span>
                </button>
                <button class="option-button" data-unidad="tdi">
                    <span class="option-icon">💻</span>
                    <span class="option-text">TDI - Sistemas</span>
                </button>
                <button class="option-button" data-unidad="ugr">
                    <span class="option-icon">🚧</span>
                    <span class="option-text">UGR</span>
                </button>
                <button class="option-button" data-unidad="dio">
                    <span class="option-icon">👥</span>
                    <span class="option-text">DIO</span>
                </button>
            </div>
            <button class="option-button back-button" data-action="back">
                <span class="option-icon">⬅️</span>
                <span class="option-text">Volver al menú principal</span>
            </button>
        `;
        
        renderOptions(unidadesHTML);
        
        document.querySelectorAll('[data-unidad]').forEach(button => {
            button.addEventListener('click', function() {
                const unidad = this.getAttribute('data-unidad');
                redirectToUnidad(unidad);
            });
        });
        
        addBackButtonListener();
    }
    
    function showDenunciaReclamoOptions() {
        addMessage("Puedes realizar una denuncia o reclamo a través de nuestro sistema ODECO. Selecciona el tipo:", 'bot');
        
        const denunciaHTML = `
            <button class="option-button" data-tipo="DENUNCIA">
                <span class="option-icon">🚨</span>
                <span class="option-text">Realizar Denuncia</span>
            </button>
            <button class="option-button" data-tipo="RECLAMO">
                <span class="option-icon">📝</span>
                <span class="option-text">Realizar Reclamo</span>
            </button>
            <button class="option-button" data-tipo="SEGUIMIENTO">
                <span class="option-icon">📊</span>
                <span class="option-text">Realizar Seguimiento</span>
            </button>
            <button class="option-button back-button" data-action="back">
                <span class="option-icon">⬅️</span>
                <span class="option-text">Volver al menú principal</span>
            </button>
        `;
        
        renderOptions(denunciaHTML);
        
        document.querySelectorAll('[data-tipo]').forEach(button => {
            button.addEventListener('click', function() {
                const tipo = this.getAttribute('data-tipo');
                redirectToOdeco(tipo);
            });
        });
        
        addBackButtonListener();
    }
    
    function showConsultasOptions() {
        addMessage("Puedes consultar tus deudas a través del sistema RUAT. Selecciona el tipo de consulta:", 'bot'); 
        const consultasHTML = `
            <button class="option-button" data-consulta="actividades">
                <span class="option-icon">🏢</span>
                <span class="option-text">Actividades Económicas</span>
            </button>
            <button class="option-button" data-consulta="vehiculos">
                <span class="option-icon">🚗</span>
                <span class="option-text">Deuda Vehículos</span>
            </button>
            <button class="option-button" data-consulta="inmuebles">
                <span class="option-icon">🏠</span>
                <span class="option-text">Deuda Inmuebles</span>
            </button>
            <button class="option-button back-button" data-action="back">
                <span class="option-icon">⬅️</span>
                <span class="option-text">Volver al menú principal</span>
            </button>
        `;        
        renderOptions(consultasHTML);
        document.querySelectorAll('[data-consulta]').forEach(button => {
            button.addEventListener('click', function() {
                const consulta = this.getAttribute('data-consulta');
                redirectToConsulta(consulta);
            });
        });
        addBackButtonListener();
    }

    async function showGovernmentSystemsOptions() {
        addMessage("Estoy consultando la lista actualizada de sistemas de Gobierno Electrónico...", 'bot');
        const systems = await loadGovernmentSystems();
        if (!systems.length) {
            addMessage("No pude cargar la lista de sistemas en este momento. Intenta nuevamente en unos segundos.", 'bot');
            return;
        }

        const systemsHTML = systems.slice(0, 10).map(system => `
            <button class="option-button" data-system-url="${escapeHtml(system.url)}" data-system-name="${escapeHtml(system.name)}">
                <span class="option-icon">💻</span>
                <span class="option-text">${escapeHtml(system.name)} - ${escapeHtml(system.status || 'Disponible')}</span>
            </button>
        `).join('') + `
            <button class="option-button back-button" data-action="back">
                <span class="option-icon">⬅️</span>
                <span class="option-text">Volver al menú principal</span>
            </button>
        `;

        renderOptions(systemsHTML);
        document.querySelectorAll('[data-system-url]').forEach(button => {
            button.addEventListener('click', function() {
                const url = this.getAttribute('data-system-url');
                const name = this.getAttribute('data-system-name');
                if (url) {
                    addMessage(`Abriendo ${name}...`, 'bot');
                    window.open(url, '_blank');
                } else {
                    addMessage(`${name} no tiene enlace público registrado.`, 'bot');
                }
            });
        });
        addBackButtonListener();
    }

    function showSeguimientoOptions() {
        addMessage("Para hacer seguimiento de un caso, puedes ingresar al sistema ODECO y usar tu código o referencia.", 'bot');
        const seguimientoHTML = `
            <button class="option-button" data-tipo="SEGUIMIENTO">
                <span class="option-icon">📊</span>
                <span class="option-text">Abrir seguimiento ODECO</span>
            </button>
            <button class="option-button back-button" data-action="back">
                <span class="option-icon">⬅️</span>
                <span class="option-text">Volver al menú principal</span>
            </button>
        `;

        renderOptions(seguimientoHTML);
        document.querySelectorAll('[data-tipo]').forEach(button => {
            button.addEventListener('click', function() {
                redirectToOdeco(this.getAttribute('data-tipo'));
            });
        });
        addBackButtonListener();
    }
    
    function addBackButtonListener() {
        const backButton = document.querySelector('[data-action="back"]');
        if (backButton) {
            backButton.addEventListener('click', function() {
                goBack();
            });
        }
    }
    function goBack() {
        if (navigationStack.length > 1) {
            navigationStack.pop();
        }
        
        const previousPage = navigationStack[navigationStack.length - 1];
        
        switch(previousPage) {
            case 'main':
                addMessage("¿En qué más puedo ayudarte?", 'bot');
                showMainOptions();
                break;
            case 'unidades':
                showUnidadesOptions();
                break;
            case 'denuncia-reclamo':
                showDenunciaReclamoOptions();
                break;
            case 'consultas':
                showConsultasOptions();
                break;
        }
    }
    
    function handleOptionSelection(option) {
        switch(option) {
            case 'unidades':
                navigationStack.push('unidades');
                showUnidadesOptions();
                break;
            case 'consultas':
                navigationStack.push('consultas');
                showConsultasOptions();
                break;
            case 'sistemas':
                navigationStack.push('sistemas');
                showGovernmentSystemsOptions();
                break;
            case 'deportes':
                redirectToApp('deportes', 'Redirigiendo al sistema de reservas deportivas...');
                break;
            case 'noticias':
                redirectToNoticias();
                break;
            case 'quillacollo':
                redirectToInfo();
                break;
            case 'denuncia-reclamo':
                navigationStack.push('denuncia-reclamo');
                showDenunciaReclamoOptions();
                break;
            case 'contacto':
                redirectToContacto();
                break;
        }
    }
    
    function redirectToUnidad(unidad) {
        const unidadNames = {
            'agricola': 'Agrícola',
            'cultura': 'Cultura',
            'educacion': 'Educación',
            'turismo': 'Turismo',
            'zoonosis': 'Zoonosis',
            'pecuaria': 'Pecuaria',
            'riegos': 'Riegos',
            'red-monica': 'Red Mónica',
            'preservacion-ambiental': 'Preservación Ambiental',
            'recursos-naturales': 'Recursos Naturales',
            'parques-jardines': 'Parques y Jardines',
            'forestal': 'Forestal',
            'tdi': 'TDI - Sistemas',
            'ugr': 'UGR',
            'dio': 'DIO'
        };
        
        const urls = {
            'agricola': 'modules/unidades/index-Agricola.html',
            'cultura': 'modules/unidades/index-Cultura.html',
            'educacion': 'modules/unidades/index-Educacion.html',
            'turismo': 'modules/unidades/index-Turismo.html',
            'zoonosis': 'modules/unidades/index-Zoonosis.html',
            'pecuaria': 'modules/unidades/index-Pecuaria.html',
            'riegos': 'modules/unidades/index-Riegos.html',
            'red-monica': 'modules/unidades/index-Red-Monica.html',
            'preservacion-ambiental': 'modules/unidades/index-Preservacion-ambiental.html',
            'recursos-naturales': 'modules/unidades/index-Recursos-naturales.html',
            'parques-jardines': 'modules/unidades/index-Parques-jardines.html',
            'forestal': 'modules/unidades/index-Forestal.html',
            'tdi': 'modules/unidades/index-TDI.html',
            'ugr': 'modules/unidades/index-UGR.html',
            'dio': 'modules/unidades/index-DIO.html'
        };
        
        const url = urls[unidad] || 'modules/unidades/';
        const name = unidadNames[unidad] || unidad;
        
        addMessage(`Redirigiendo a la unidad de ${name}...`, 'bot');
        setTimeout(() => {
            window.location.href = siteUrl(url);
        }, 1000);
    }
    
    function redirectToNoticias() {
        addMessage("Redirigiendo a las últimas noticias del GAMQ...", 'bot');
        setTimeout(() => {
            window.location.href = siteUrl('pages/news.html');
        }, 1000);
    }
    
    function redirectToInfo() {
        addMessage("Redirigiendo a la información sobre Quillacollo...", 'bot');
        setTimeout(() => {
            window.location.href = siteUrl('pages/about.html');
        }, 1000);
    }
    
    function redirectToOdeco(tipo) {
        addMessage(`Redirigiendo al formulario de ${tipo.toLowerCase()}...`, 'bot');
        setTimeout(() => {
            window.location.href = `/app/odeco?tipo=${tipo}`;
        }, 1000);
    }

    
    function redirectToContacto() {
        addMessage("Te conectaré con nuestro equipo de atención a través de WhatsApp...", 'bot');
        setTimeout(() => {
            window.open('https://wa.me/59169528883?text=Hola,%20necesito%20información%20sobre%20los%20servicios%20del%20GAMQ', '_blank');
        }, 1000);
    }
    
    function redirectToConsulta(tipo) {
        const consultaInfo = {
            'actividades': {
                name: 'Actividades Económicas',
                url: 'https://www.ruat.gob.bo/actividadeseconomicas/MenuActividadesEconomicas.jsf',
                description: 'Consulta pagos QR, deudas, datos técnicos y más'
            },
            'vehiculos': {
                name: 'Deuda de Vehículos',
                url: 'https://www.ruat.gob.bo/vehiculos/MenuVehiculos.jsf',
                description: 'Consulta deudas, infracciones, ITV y pagos de vehículos'
            },
            'inmuebles': {
                name: 'Deuda de Inmuebles',
                url: 'https://www.ruat.gob.bo/inmuebles/MenuInmuebles.jsf',
                description: 'Consulta deudas de propiedades e inmuebles'
            }
        };
        
        const info = consultaInfo[tipo];
        addMessage(`Redirigiendo a la consulta de ${info.name}. ${info.description}.`, 'bot');
        setTimeout(() => {
            window.open(info.url, '_blank');
        }, 1500);
    }
    
    function redirectToDeportes() {
        addMessage("Redirigiendo al sistema de reservas deportivas. Podrás reservar canchas y complejos deportivos del municipio...", 'bot');
        setTimeout(() => {
            window.open('/app/deportes', '_blank');
        }, 1500);
    }

    function redirectToApp(app, message = null, params = {}) {
        if (message) {
            addMessage(message, 'bot');
        }
        const query = new URLSearchParams(params).toString();
        const url = `/app/${app}` + (query ? `?${query}` : '');

        setTimeout(() => {
            window.location.href = url;
        }, 1000);
    }

    
    showMainOptions();
}

document.addEventListener('DOMContentLoaded', function() {
    if (document.getElementById('chatbot-container')) {
        initializeChatbot();
    }
});


Youez - 2016 - github.com/yon3zu
LinuXploit