// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * @module     block_mwa_dashboard/alerts
 * @copyright  2026 Bruno Porto
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
define(['block_mwa_dashboard/dashboardstore'], function(Store) {

    'use strict';

    var window = Store.windowFacade();

    (function () {
      'use strict';
    
      /*
       * tr() lê Store.getStrings() diretamente — o mesmo objeto que o PHP injeta
       * via dashboard_renderer.php. Isso garante que a tradução funciona mesmo que
       * window.MWADashboard ainda não exista quando o script é carregado.
       * Idêntico ao padrão do actioncenter.js (ctx().tr aponta para esta mesma lógica).
       */
      function tr(key) {
        var S = Store.getStrings() || {};
        var v = Object.prototype.hasOwnProperty.call(S, key) ? S[key] : '';
        if (typeof v === 'string' && v && !/^\[\[.*\]\]$/.test(v)) return v;
        return key;
      }
    
      /* substitui {n} na string traduzida */
      function trN(key, n) {
        return tr(key).replace('{n}', n);
      }
    
      function esc(v) {
        return String(v === undefined || v === null ? '' : v)
          .replace(/[&<>"']/g, function (c) {
            return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c];
          });
      }
    
      function norm(v) { return (v === undefined || v === null) ? '' : String(v).trim(); }
      function lower(v) { return norm(v).toLowerCase(); }
    
      function getLogs() {
        if (window.MWADashboard && window.MWADashboard.state) return window.MWADashboard.state.logs || [];
        return [];
      }
    
      /* ── getDaysAgo ── */
      function getDaysAgo(date) {
        if (!date) return 9999;
        return Math.floor((Date.now() - date.getTime()) / 86400000);
      }
    
      /* ── parseDate a partir de um log ── */
      function parseDate(log) {
        if (log._ts) return new Date(Number(log._ts) * 1000);
        var s = norm(log.hora);
        var m = s.match(/(\d{2})\/(\d{2})\/(\d{2}),\s*(\d{2}):(\d{2})/);
        if (m) return new Date(2000 + Number(m[3]), Number(m[2]) - 1, Number(m[1]), Number(m[4]), Number(m[5]));
        return null;
      }
    
      /* ── agrupa logs por aluno ── */
      function groupByStudent() {
        var byStudent = {};
        getLogs().forEach(function (r) {
          var name = norm(r.nomecompleto);
          if (!name) return;
          var key  = lower(norm(r.email)) || lower(name);
          if (!byStudent[key]) byStudent[key] = { name: name, email: norm(r.email), logs: [] };
          var clone = Object.assign({}, r);
          clone.date = parseDate(r);
          byStudent[key].logs.push(clone);
        });
        return byStudent;
      }
    
      /* ════════════════════════════════════════════
         BUILD: detecta os 6 padrões de alerta
      ════════════════════════════════════════════ */
      var SA_DATA = null;
      var SA_STUDENTS_MAP = {}; // id_card → array de students
    
      function buildSmartAlertData() {
        if (SA_DATA && SA_DATA.built) return SA_DATA;
    
        var byStudent = groupByStudent();
        var keys = Object.keys(byStudent);
    
        /* Alert 1 — Viewed but not submitted */
        var sawNotSubmit = [];
        keys.forEach(function (k) {
          var s   = byStudent[k];
          var evs = s.logs;
          var saw = evs.some(function (e) {
            var ev   = lower(norm(e.nomedoevento));
            var comp = lower(norm(e.componente));
            // only count "viewed" events for assignments
            return (comp === 'assignment' || comp === 'tarefa') &&
                   (ev.indexOf('course module viewed') !== -1 ||
                    ev.indexOf('submission status viewed') !== -1 ||
                    ev.indexOf('submission_status_viewed') !== -1 ||
                    ev.indexOf('viewed') !== -1);
          });
          var submitted = evs.some(function (e) {
            var ev   = lower(norm(e.nomedoevento));
            var comp = lower(norm(e.componente));
            return (comp === 'assignment' || comp === 'tarefa') &&
                   (ev === 'submission submitted' ||
                    ev === 'file uploaded' ||
                    ev.indexOf('submit') !== -1 ||
                    ev.indexOf('upload') !== -1);
          });
          if (saw && !submitted) sawNotSubmit.push({ name: s.name, email: s.email });
        });
    
        /* Alert 2 — Sharp drop semana a semana */
        var sharpDrop = [];
        keys.forEach(function (k) {
          var s    = byStudent[k];
          var evs  = s.logs.filter(function (r) { return r.date; });
          var thisWeek = evs.filter(function (r) { return getDaysAgo(r.date) <= 7; }).length;
          var lastWeek = evs.filter(function (r) { return getDaysAgo(r.date) > 7 && getDaysAgo(r.date) <= 14; }).length;
          if (lastWeek >= 5 && thisWeek < lastWeek * 0.4) {
            sharpDrop.push({ name: s.name, email: s.email, drop: Math.round((1 - thisWeek / lastWeek) * 100) });
          }
        });
    
        /* Alert 3 — Early ghosts */
        var ghosts = [];
        keys.forEach(function (k) {
          var s   = byStudent[k];
          var evs = s.logs.filter(function (r) { return r.date; })
                          .sort(function (a, b) { return a.date - b.date; });
          if (!evs.length) return;
          var first         = evs[0].date;
          var last          = evs[evs.length - 1].date;
          var daysSinceLast = getDaysAgo(last);
          var activePeriod  = Math.round((last - first) / 86400000);
          if (activePeriod <= 14 && daysSinceLast > 21)
            ghosts.push({ name: s.name, email: s.email, daysSinceLast: daysSinceLast });
        });
    
        /* Alert 4 — Symbolic access (≤2 dias distintos) */
        var symbolic = [];
        keys.forEach(function (k) {
          var s      = byStudent[k];
          var evs    = s.logs.filter(function (r) { return r.date; });
          var daySet = new Set(evs.map(function (r) { return r.date.toDateString(); }));
          if (daySet.size <= 2)
            symbolic.push({ name: s.name, email: s.email, days: daySet.size });
        });
    
        /* Alert 5 — Madrugadores (>45% entre 0h–5h) */
        var nightOwls = [];
        keys.forEach(function (k) {
          var s    = byStudent[k];
          var evs  = s.logs.filter(function (r) { return r.date; });
          var dawn = evs.filter(function (r) { return r.date.getHours() < 5; }).length;
          if (evs.length >= 10 && dawn / evs.length >= 0.45)
            nightOwls.push({ name: s.name, email: s.email, pct: Math.round(dawn / evs.length * 100) });
        });
    
        /* Alert 6 — Reactivated (gap ≥10 days, returned in last 5 days) */
        var reactivated = [];
        keys.forEach(function (k) {
          var s   = byStudent[k];
          var evs = s.logs.filter(function (r) { return r.date; })
                          .sort(function (a, b) { return a.date - b.date; });
          if (evs.length < 2) return;
          var last = evs[evs.length - 1];
          if (getDaysAgo(last.date) > 5) return;
          var recent = evs.filter(function (r) { return getDaysAgo(r.date) <= 5; });
          var before = evs.filter(function (r) { return getDaysAgo(r.date) > 5; });
          if (!before.length) return;
          var gap = Math.round((recent[0].date - before[before.length - 1].date) / 86400000);
          if (gap >= 10)
            reactivated.push({ name: s.name, email: s.email, gap: gap });
        });
    
        SA_DATA = { built: true, sawNotSubmit: sawNotSubmit, sharpDrop: sharpDrop,
                    ghosts: ghosts, symbolic: symbolic, nightOwls: nightOwls, reactivated: reactivated };
        return SA_DATA;
      }
    
      /* ════════════════════════════════════════════
         RENDER KPIs — lê Store.getStrings() via tr() em runtime
      ════════════════════════════════════════════ */
      function renderAlertKPIs(d) {
        var container = document.getElementById('saKpisRow');
        if (!container) return;
    
        var kpis = [
          { cls: 'c-red',    icon: '👁',  lk: 'alert_kpi_viu_label',      dk: 'alert_kpi_viu_delta',      tk: 'alert_kpi_viu_tip',      val: d.sawNotSubmit.length },
          { cls: 'c-amber',  icon: '📉', lk: 'alert_kpi_queda_label',    dk: 'alert_kpi_queda_delta',    tk: 'alert_kpi_queda_tip',    val: d.sharpDrop.length    },
          { cls: 'c-purple', icon: '👻', lk: 'alert_kpi_fantasma_label', dk: 'alert_kpi_fantasma_delta', tk: 'alert_kpi_fantasma_tip', val: d.ghosts.length       },
          { cls: 'c-blue',   icon: '⚡', lk: 'alert_kpi_simbol_label',   dk: 'alert_kpi_simbol_delta',   tk: 'alert_kpi_simbol_tip',   val: d.symbolic.length     },
          { cls: 'c-teal',   icon: '🔄', lk: 'alert_kpi_reat_label',     dk: 'alert_kpi_reat_delta',     tk: 'alert_kpi_reat_tip',     val: d.reactivated.length  },
          { cls: 'c-green',  icon: '🌙', lk: 'alert_kpi_madru_label',    dk: 'alert_kpi_madru_delta',    tk: 'alert_kpi_madru_tip',    val: d.nightOwls.length    },
        ];
    
        // Delta: dividir logs em metade recente vs anterior
        var dc = window.MWADeltaChip;
        var alLogs = (window.MWADashboard&&window.MWADashboard.state&&window.MWADashboard.state.logs)||[];
        var alDated = alLogs.map(function(l){var t=l&&l.timecreated?l.timecreated*1000:0;return t?{l:l,t:t}:null;}).filter(Boolean).sort(function(a,b){return a.t-b.t;});
        var alMid=Math.floor(alDated.length/2),alPrv={},alCur={};
        alDated.slice(0,alMid).forEach(function(x){var n=(x.l.nomecompleto||'').trim().toLowerCase();if(n)alPrv[n]=true;});
        alDated.slice(alMid).forEach(function(x){var n=(x.l.nomecompleto||'').trim().toLowerCase();if(n)alCur[n]=true;});
        function alDelta(arr,inv){if(!dc||!alDated.length)return '';var c=arr.filter(function(s){return alCur[(s.name||'').trim().toLowerCase()];}).length;var p=arr.filter(function(s){return alPrv[(s.name||'').trim().toLowerCase()];}).length;return dc(c,p,inv);}
        var kpiDeltas=[alDelta(d.sawNotSubmit,true),alDelta(d.sharpDrop,true),alDelta(d.ghosts,true),alDelta(d.symbolic,true),alDelta(d.reactivated,false),alDelta(d.nightOwls,false)];
        Store.renderHtml(container, kpis.map(function (kpi, i) {
          return '<div class="sa-kpi ' + kpi.cls + '">'
            + '<div class="sa-kpi-label">' + kpi.icon + ' ' + esc(tr(kpi.lk)) + (kpiDeltas[i]||'') + '</div>'
            + '<div class="sa-kpi-val">' + kpi.val + '</div>'
            + '<div class="sa-kpi-delta">' + esc(tr(kpi.dk)) + '</div>'
            + '</div>';
        }).join(''));
      }
    
      /* ════════════════════════════════════════════
         saBlock — todas as strings via tr() em runtime
      ════════════════════════════════════════════ */
      function saBlock(cls, icon, titleKey, tipKey, students, extraFn) {
        var id = 'sa_' + Math.random().toString(36).slice(2, 7);
        SA_STUDENTS_MAP[id] = students; // guardar para uso no click de mensagem
        var n  = students.length;
    
        var fmt = function (s) {
          var parts = norm(s.name).split(/\s+/).filter(Boolean);
          var short = (parts[0] || '') + (parts.length > 1 ? ' ' + parts[parts.length - 1] : '');
          var extra = extraFn ? extraFn(s) : '';
          return '<strong>' + esc(short) + '</strong>'
            + (extra ? ' <span style="color:var(--subtle);font-size:.72rem;">(' + esc(extra) + ')</span>' : '');
        };
    
        var shortN = students.slice(0, 5).map(fmt).join(' · ');
        var allN   = students.map(fmt).join(' · ');
        var moreN  = n > 5
          ? ' <span class="sa-toggle-link" onclick="window.MWAAlerts.saToggle(\'' + id + '\')">'
            + esc(trN('alert_see_more', n - 5)) + '</span>'
          : '';
        var lessN  = ' <span class="sa-toggle-link" onclick="window.MWAAlerts.saToggle(\'' + id + '\')">'
            + esc(tr('alert_see_less')) + '</span>';
    
        var emails = students.map(function (s) { return s.email; }).filter(Boolean);
    
        return '<div class="smart-alert ' + cls + '" id="' + id + '">'
          + '<div class="sa-icon">' + icon + '</div>'
          + '<div class="sa-body">'
            + '<div class="sa-title">' + esc(tr(titleKey)) + ' <span class="sa-count">' + n + '</span></div>'
            + '<div class="sa-names">'
              + '<span class="sa-short">' + shortN + moreN + '</span>'
              + '<span class="sa-full" style="display:none;">' + allN + lessN + '</span>'
            + '</div>'
            + '<div class="sa-tip">💡 ' + esc(tr(tipKey)) + '</div>'
            + '<div class="sa-actions">'
              + (students.length
                  ? '<button class="sa-btn-primary" data-sa-bulk="1">✉️ ' + esc(tr('alert_email_all')) + '</button>'
                  : '')
              + '<button class="sa-btn-ghost" onclick="window.showPage && window.showPage(\'engagement\')">'
                + esc(tr('alert_view_prediction')) + '</button>'
            + '</div>'
          + '</div>'
          + '</div>';
      }
    
      function saToggle(id) {
        var el = document.getElementById(id);
        if (!el) return;
        var s = el.querySelector('.sa-short');
        var a = el.querySelector('.sa-full');
        if (!s || !a) return;
        if (a.style.display === 'none') { a.style.display = ''; s.style.display = 'none'; }
        else                            { a.style.display = 'none'; s.style.display = ''; }
      }
    
      /* ════════════════════════════════════════════
         RENDER PRINCIPAL
      ════════════════════════════════════════════ */
      function renderSmartAlerts(badgeOnly) {
        SA_DATA = null;
        SA_STUDENTS_MAP = {};
        var d     = buildSmartAlertData();
        var total = d.sawNotSubmit.length + d.sharpDrop.length + d.ghosts.length
                  + d.symbolic.length + d.nightOwls.length + d.reactivated.length;
    
        var badge = document.getElementById('navAlertBadge');
        if (badge) badge.textContent = total || '0';
    
        if (badgeOnly) return;
    
        renderAlertKPIs(d);
    
        var blocks = [];
    
        if (d.sawNotSubmit.length)
          blocks.push(saBlock('sa-danger',  '📬', 'alert_block_viu_title',   'alert_block_viu_tip',   d.sawNotSubmit, null));
    
        if (d.sharpDrop.length)
          blocks.push(saBlock('sa-warning', '📉', 'alert_block_queda_title', 'alert_block_queda_tip', d.sharpDrop,
            function (s) { return trN('alert_extra_queda', s.drop); }));
    
        if (d.symbolic.length)
          blocks.push(saBlock('sa-danger',  '⚡', 'alert_block_simbol_title','alert_block_simbol_tip', d.symbolic,
            function (s) { return trN('alert_extra_dias', s.days); }));
    
        if (d.ghosts.length)
          blocks.push(saBlock('sa-purple',  '👻', 'alert_block_ghost_title', 'alert_block_ghost_tip', d.ghosts,
            function (s) { return trN('alert_extra_sumiu', s.daysSinceLast); }));
    
        if (d.reactivated.length)
          blocks.push(saBlock('sa-success', '🔄', 'alert_block_reat_title',  'alert_block_reat_tip',  d.reactivated,
            function (s) { return trN('alert_extra_ausente', s.gap); }));
    
        if (d.nightOwls.length)
          blocks.push(saBlock('sa-info',    '🌙', 'alert_block_madru_title', 'alert_block_madru_tip', d.nightOwls,
            function (s) { return trN('alert_extra_madru', s.pct); }));
    
        var list = document.getElementById('saAlertList');
        if (!list) return;
    
        Store.renderHtml(list, blocks.length
          ? '<div class="smart-alerts-wrap">' + blocks.join('') + '</div>'
          : '<div class="sa-empty"><div class="sa-empty-icon">✅</div><p>' + esc(tr('alerts_no_data')) + '</p></div>');

        // Delegated handler for message buttons (data-sa-bulk)
        var container = document.getElementById('saAlertList');
        if (container) {
          container.addEventListener('click', function(e) {
            var btn = e.target.closest('[data-sa-bulk]');
            if (!btn) return;
            e.stopPropagation();
            // Encontrar o card pai para recuperar o id
            var card = btn.closest('.smart-alert');
            var cardId = card ? card.id : null;
            var studs = cardId ? (SA_STUDENTS_MAP[cardId] || []) : [];
            if (!studs.length) return;
            var targets = studs.map(function(s) {
              return {name: s.name||'', email: s.email||'', userid: s.userid||0};
            }).filter(function(t) { return t.name; });
            if (!targets.length) return;
            if (targets.length === 1) {
              if (window.MWAInterventions && window.MWAInterventions.quickMessage) {
                window.MWAInterventions.quickMessage(targets[0].name, targets[0].email, targets[0].userid, '');
              }
            } else if (window.MWAActionCenter && typeof window.MWAActionCenter.openBulkModal === 'function') {
              window.MWAActionCenter.openBulkModal(targets);
            } else if (window.MWAInterventions && window.MWAInterventions.quickMessage) {
              window.MWAInterventions.quickMessage(targets[0].name, targets[0].email, targets[0].userid, '');
            }
          }, {once: false});
        }
      }
    
      window.MWAAlerts = {
        render:   renderSmartAlerts,
        saToggle: saToggle,
        reset:    function () { SA_DATA = null; SA_STUDENTS_MAP = {}; }
      };
    
    })();

    return window.MWAAlerts;
});
