import { backendUrl } from './config.js'
const byId = (id) => document.getElementById(id);
let chartLine, chartStacked, chartIP;
let chartCorrelation = null;
const translations = {
  ru: {
    meta_title: "AI Интегрированный Анализ",
    show_chart: "Показать график",
    timeline_chart: "График аномалий по времени",
    correlation_matrix: "Матрица корреляции типов аномалий",
    correlation_graph: "Граф сильных связей",
    anomaly_log: "Журнал мультианомалий",
    escalate: "Эскалировать",
    only_unescalated: "Только неэскалированные",
    time: "Время",
    types: "Типы",
    level: "Уровень",
    escalated: "Эскалировано",
    status_loading: "⏳ Загрузка...",
    meta_analysis: "Системный мета-анализ",
    status_error: "⚠️ Ошибка",
    refresh_check: "Проверить снова",
    auto_refresh: "Автообновление",
    interval_label: "Интервал",
    status_done: "✅ Готово",
    interval: "Интервал:",
    per_minute: "по минутам",
    per_hour: "по часам",
    per_day: "по дням",
    period_minutes: "Период (минут):",
    from_time: "С какого времени (опц.):",
    min_anomalies: "Мин. кол-во аномалий (опц.):",
    ip_filter: "Фильтрация по IP-адресу",
    enter_ip: "Введите IP:",
    aggregation_interval: "Интервал агрегации:",
    analysis_period: "Анализ за (минут):",
    correlation_threshold: "Порог корреляции:",
    build_matrix: "Построить матрицу",
    strong_correlation_graph: "🧩 Граф сильных связей",
    positive_corr: "— положительная корреляция",
    negative_corr: "— отрицательная корреляция",
    line_weight: "толщина = сила связи",
    multi_timeline: "🧨 Мультианомалии по времени",
    multi_log: "📄 Журнал мультианомалий",
    graphical_analysis: "Графическое представление аномалий",
    meta_analysis_hint: "Анализ объединяет поведение всех потоков за последние N минут, чтобы выявить сложные отклонения в работе системы.",
    auto_refresh_hint: "Если включено, мета-анализ будет автоматически повторяться каждые N минут.",
    auto_refresh_interval_hint: "Установка интервала автообновления в минутах",
    show_limit: "Показать:",
    status_loading: "⏳ Выполняется мета-анализ...",
    status_error: "⚠️ Ошибка анализа",
    meta_anomaly_detected: "Обнаружено отклонение поведения системы",
    meta_system_ok: "Система работает в нормальном режиме",
    graphical_analysis: "🧠 Графическое представление аномалий",
    interval: "Интервал:",
    per_minute: "по минутам",
    per_hour: "по часам",
    per_day: "по дням",
    period_minutes: "Период (минут):",
    from_time: "С какого времени (опц.):",
    min_anomalies: "Мин. кол-во аномалий (опц.):",
    show_chart: "Показать график",
    line_chart: "Линейный график (по типам)",
    interval_tooltip: "Интервал агрегации по времени",
    period_minutes_tooltip: "За сколько минут назад собирать данные",
    from_time_tooltip: "Начальная временная точка (если нужно)",
    min_anomalies_tooltip: "Пороговое значение аномалий для отображения",
    multi_timeline: "🧨 Мультианомалии по времени",
    about_multi: "❓ О мультианомалиях",
    multi_modal_title: "О мультианомалиях",
    stacked_area_chart: "Stacked Area (суммарно)"
  },
  en: {
    meta_title: "AI Integrated Analysis",
    show_chart: "Show Chart",
    timeline_chart: "Anomaly Timeline",
    correlation_matrix: "Correlation Matrix of Anomaly Types",
    correlation_graph: "Strong Correlation Graph",
    anomaly_log: "Multi-Anomaly Log",
    escalate: "Escalate",
    only_unescalated: "Only Unescalated",
    time: "Time",
    types: "Types",
    level: "Level",
    escalated: "Escalated",
    status_loading: "⏳ Loading...",
    meta_analysis: "System Meta Analysis",
    refresh_check: "Check again",
    auto_refresh: "Autorefresh",
    interval_label: "Interval",
    status_error: "⚠️ Error",
    status_done: "✅ Done",
    interval: "Interval:",
    per_minute: "per minute",
    per_hour: "per hour",
    per_day: "per day",
    period_minutes: "Period (minutes):",
    from_time: "From time (optional):",
    min_anomalies: "Min. anomaly count (optional):",
    ip_filter: "IP Address Filter",
    enter_ip: "Enter IP:",
    aggregation_interval: "Aggregation Interval:",
    analysis_period: "Analysis Period (minutes):",
    correlation_threshold: "Correlation Threshold:",
    build_matrix: "Build Matrix",
    strong_correlation_graph: "🧩 Strong Correlation Graph",
    positive_corr: "— positive correlation",
    negative_corr: "— negative correlation",
    line_weight: "line thickness = strength",
    multi_timeline: "🧨 Multi-Anomalies Over Time",
    multi_log: "📄 Multi-Anomaly Log",
    graphical_analysis: "Graphical representation of anomalies",
    meta_analysis_hint: "Analysis combines behavior from all streams over the last N minutes to detect complex system anomalies.",
    auto_refresh_hint: "If enabled, meta-analysis will automatically run every N minutes.",
    auto_refresh_interval_hint: "Set avtorefresh interval in minutes",
    show_limit: "Show:",
    status_loading: "⏳ Running meta-analysis...",
    status_error: "⚠️ Analysis error",
    meta_anomaly_detected: "Behavioral deviation detected",
    meta_system_ok: "System is operating normally",
    graphical_analysis: "🧠 Graphical Anomaly Overview",
    interval: "Interval:",
    per_minute: "per minute",
    per_hour: "per hour",
    per_day: "per day",
    period_minutes: "Period (minutes):",
    from_time: "From time (optional):",
    min_anomalies: "Min. anomaly count (optional):",
    show_chart: "Show Chart",
    line_chart: "Line Chart (by types)",
    interval_tooltip: "Time aggregation interval",
period_minutes_tooltip: "How many minutes back to collect data",
from_time_tooltip: "Start time (optional)",
min_anomalies_tooltip: "Threshold of anomalies to display",
multi_timeline: "🧨 Multi-Anomalies Over Time",
    about_multi: "❓ About Multi-Anomalies",
    multi_modal_title: "About Multi-Anomalies",
    stacked_area_chart: "Stacked Area (summary)"
  }
};

    
const t = (key) => {
  const lang = localStorage.getItem('lang') || 'ru';
  return translations[lang]?.[key] || key;
};

const applyLanguage = (lang) => {
  const dict = translations[lang] || translations['ru'];

  // Update texts
  document.querySelectorAll('[data-i18n]').forEach(el => {
    const key = el.getAttribute('data-i18n');
    if (dict[key]) el.textContent = dict[key];
  });

  // Update titles (title)
  document.querySelectorAll('[data-i18n-title]').forEach(el => {
    const key = el.getAttribute('data-i18n-title');
    if (dict[key]) el.title = dict[key];
  });

  localStorage.setItem('lang', lang);
};



const initLanguage = () => {
  const lang = localStorage.getItem('lang') || 'ru';
  const select = document.getElementById('langSelect');
  if (select) select.value = lang;
  applyLanguage(lang);
  if (select) {
    select.addEventListener('change', (e) => {
      applyLanguage(e.target.value);
    });
  }
};
initLanguage();
document.getElementById('loadTimeline').addEventListener('click', async () => {
  const interval = byId('intervalSelect').value;
  const minutes = parseInt(byId('minutesBack').value) || 60;
  const fromTime = byId('fromTime').value;
  const minCount = parseInt(byId('minCount').value) || 0;
  const status = byId('timelineStatus');
  status.textContent = '⏳ Building graphics...';
  
  const params = new URLSearchParams({
    interval,
    minutes: minutes.toString()
  });

  if (fromTime) params.append('from_time', fromTime);
  if (minCount > 0) params.append('min_count', minCount.toString());

  try {
    const res = await fetch(`${backendUrl}/api/anomaly_timeline_all?${params}`);
    const data = await res.json();
    if (data.error) throw new Error(data.error);

    const labels = data.timeline.map(t => t.time);
    const eventTypes = ['flow', 'http', 'dns', 'tls'];

    const colorMap = {
      flow: '#ff6384',
      http: '#36a2eb',
      dns: '#ffce56',
      tls: '#4bc0c0'
    };

    const datasets = eventTypes.map(type => ({
      label: type.toUpperCase(),
      data: data.timeline.map(t => t[type] || 0),
      fill: false,
      tension: 0.3,
      borderColor: colorMap[type],
      backgroundColor: colorMap[type] + '80'
    }));

    const stackedDatasets = datasets.map(d => ({
      ...d,
      fill: true
    }));

    if (chartLine) chartLine.destroy();
    if (chartStacked) chartStacked.destroy();

    const ctx1 = byId('timelineChartLine').getContext('2d');
    chartLine = new Chart(ctx1, {
      type: 'line',
      data: { labels, datasets },
      options: {
        responsive: true,
        plugins: {
          title: {
            display: true,
            text: `Suricata anomalies by types (${interval})`
          }
        },
        scales: {
          y: {
            beginAtZero: true,
            title: { display: true, text: 'Nubber of anomalies' }
          },
          x: {
            ticks: {
              maxRotation: 45,
              minRotation: 45
            }
          }
        }
      }
      
    });

    const ctx2 = byId('timelineChartStacked').getContext('2d');
    chartStacked = new Chart(ctx2, {
      type: 'line',
      data: { labels, datasets: stackedDatasets },
      options: {
        responsive: true,
        plugins: {
          title: {
            display: true,
            text: `Suricata Total Anomalies (${interval})`
          }
        },
        interaction: {
          mode: 'index',
          intersect: false
        },
        stacked: true,
        scales: {
          x: {
            stacked: true,
            ticks: {
              maxRotation: 45,
              minRotation: 45
            }
          },
          y: {
            stacked: true,
            beginAtZero: true,
            title: { display: true, text: 'Total number of anomalies' }
          }
        }
      }
      
    });
    status.textContent = `✅ Building ${labels.length} points for every type of traffic`;
  } catch (err) {
    alert('Error loading data: ' + err.message);
  }
  

});

document.getElementById('filterByIpBtn').addEventListener('click', async () => {
    const ip = byId('ipFilter').value.trim();
    const status = byId('ipStatus');
    status.textContent = '';
  
    if (!ip) {
      alert('Enter IP address to filter');
      return;
    }
  
    const interval = byId('intervalSelect').value;
    const minutes = parseInt(byId('minutesBack').value) || 60;
  
    const params = new URLSearchParams({
      ip,
      interval,
      minutes: minutes.toString()
    });
  
    try {
      status.textContent = '⏳ Plotting a graph for IP...';
  
      const res = await fetch(`${backendUrl}/api/anomaly_timeline_by_ip?${params}`);
      const data = await res.json();
  
      if (data.error) throw new Error(data.error);
  
      const labels = data.timeline.map(t => t.time);
      const values = data.timeline.map(t => t.count);
  
      if (chartIP) chartIP.destroy();
      const ctx = byId('timelineChartIP').getContext('2d');
      chartIP = new Chart(ctx, {
        type: 'bar',
        data: {
          labels,
          datasets: [{
            label: `Anomalies for IP ${ip}`,
            data: values,
            backgroundColor: '#a566ff'
          }]
        },
        options: {
          responsive: true,
          plugins: {
            title: {
              display: true,
              text: `Suricata Anomalies for IP ${ip}`
            }
          },
          scales: {
            y: {
              beginAtZero: true,
              title: { display: true, text: 'Number of anomalies' }
            }
          }
        }
      });
  
      status.textContent = `✅ Found ${values.length} intervals with anomalies`;
    } catch (err) {
      status.textContent = '';
      alert('Error filtering by IP: ' + err.message);
    }
  });


  document.getElementById('loadCorrelationMatrix').addEventListener('click', async () => {
    const status = document.getElementById('correlationStatus');
    status.textContent = '⏳ Loading the correlation matrix...';
  
    const interval = byId('correlationInterval').value;
    const minutes = parseInt(byId('correlationMinutes').value) || 180;
  
    try {
      const res = await fetch(`${backendUrl}/api/anomaly_correlation_matrix?interval=${interval}&minutes=${minutes}`);
      const data = await res.json();
      if (data.error) throw new Error(data.error);
  
      const types = data.types;
      const matrix = data.matrix;
  
      if (!Array.isArray(types) || !Array.isArray(matrix) || types.length === 0) {
        status.textContent = '⚠️ No data to display';
        return;
      }
  
      Plotly.newPlot('matrixPlotlyContainer', [{
        z: matrix,
        x: types,
        y: types,
        type: 'heatmap',
        colorscale: 'RdBu',
        reversescale: true,
        zmin: -1,
        zmax: 1,
        text: matrix.map(row => row.map(v => v.toFixed(2))),
        texttemplate: "%{text}",
        textfont: {
          color: "white",
          size: 12
        },
        hoverinfo: 'x+y+text',
        showscale: true
      }], {
      
        title: `📊 Correlation matrix (${interval}, ${minutes} min)`,
        xaxis: { side: 'top' },
        yaxis: { autorange: 'reversed' },
        margin: { l: 80, r: 30, t: 60, b: 30 }
      }, {
        responsive: true
      });
  
      status.textContent = `✅ Built ${types.length}×${types.length}`;
      drawCorrelationGraph(types, matrix);

    } catch (err) {
      status.textContent = '';
      alert('Error while building Plotly chart: ' + err.message);
    }
  });
  /////
  // === Construct a graph of strong pairs ===
// 🧠 Building a strong correlation graph
function drawCorrelationGraph(types, matrix) {
  const graphContainer = document.getElementById('correlationGraph');
  const title = document.getElementById('correlationGraphTitle');
  const thresholdInput = document.getElementById('correlationThreshold');

  if (!graphContainer || !title) {
    console.warn("❌ Graph elements not found in DOM");
    return;
  }

  const threshold = parseFloat(thresholdInput?.value || '0.7');
  graphContainer.innerHTML = ''; // clearing from the previous 

  const nodes = new Set();
  const edges = [];

  for (let i = 0; i < types.length; i++) {
    for (let j = i + 1; j < types.length; j++) {
      const val = matrix[i][j];
      if (Math.abs(val) >= threshold) {
        edges.push({ source: types[i], target: types[j], value: val });
        nodes.add(types[i]);
        nodes.add(types[j]);
      }
    }
  }

  const nodeList = Array.from(nodes);

  if (nodeList.length === 0) {
    graphContainer.innerHTML = "<p style='color: gray; font-style: italic;'>There are no strong links at the chosen threshold..</p>";
    return;
  }

  // 📌 Layout of nodes on a 2x2 grid
  const grid = [
    { x: 0, y: 0 },
    { x: 3, y: 0 },
    { x: 0, y: -3 },
    { x: 3, y: -3 },
    { x: 1.5, y: 1.5 },
    { x: 4.5, y: -1.5 }
  ];
  const positions = {};
  nodeList.forEach((node, i) => {
    positions[node] = grid[i] || { x: i * 2, y: 0 };
  });

  // 🔗 Ribs
  const edgeTraces = edges.map(e => ({
    type: 'scatter',
    x: [positions[e.source].x, positions[e.target].x],
    y: [positions[e.source].y, positions[e.target].y],
    mode: 'lines',
    line: {
      width: Math.max(Math.abs(e.value) * 10, 3),
      color: e.value >= 0 ? 'rgba(120,0,200,0.8)' : 'rgba(220,20,20,0.6)'
    },
    hoverinfo: 'text',
    text: `${e.source} ↔ ${e.target}: ${e.value.toFixed(2)}`
  }));

  // ⚪ Nodes
  const nodeTrace = {
    type: 'scatter',
    x: nodeList.map(n => positions[n].x),
    y: nodeList.map(n => positions[n].y),
    mode: 'markers+text',
    marker: {
      size: 35,
      color: 'lightblue',
      line: { width: 2, color: '#333' }
    },
    text: nodeList,
    textposition: 'middle center',
    textfont: {
      size: 16,
      color: '#111',
      family: 'Arial Black'
    },
    hoverinfo: 'text'
  };

  // 📊 Building graph
  Plotly.newPlot('correlationGraph', [...edgeTraces, nodeTrace], {
    title: `Strongly Correlated Pairs (≥ ${threshold})`,
    showlegend: false,
    xaxis: { visible: false },
    yaxis: { visible: false },
    margin: { t: 50, l: 0, r: 0, b: 0 }
  });
}
const checkMetaStatus = async () => {
  const status = document.getElementById('metaStatusText');
  status.textContent = t('status_loading');

  try {
    const res = await fetch(`${backendUrl}/api/meta/check`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ window_size: 60, shift: 0 })
    });

    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const data = await res.json();

    if (data.is_anomaly) {
      status.innerHTML = `🔥 <strong>${t('meta_anomaly_detected')}</strong>`;
      status.style.color = 'darkred';
    } else {
      status.innerHTML = `✅ <strong>${t('meta_system_ok')}</strong>`;
      status.style.color = 'green';
    }
  } catch (err) {
    status.innerHTML = `⚠️ ${t('status_error')}: ${err.message}`;
    status.style.color = 'orange';
  }
};


// Manual button
document.getElementById('refreshMetaCheck').addEventListener('click', checkMetaStatus);

// Autoloading at start
checkMetaStatus();
let metaRefreshTimer = null;

/*const checkMetaStatus = async () => {
  const status = document.getElementById('metaStatusText');
  status.textContent = '⏳ A meta-analysis is being performed...';

  try {
    const res = await fetch('${backendUrl}/api/meta/check', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ window_size: 60, shift: 0 })
    });

    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const data = await res.json();

    if (data.is_anomaly) {
      status.innerHTML = `🔥 <strong>System behavior deviation detected</strong>`;
      status.style.color = 'darkred';
    } else {
      status.innerHTML = `✅ <strong>The system is operating normally.</strong>`;
      status.style.color = 'green';
    }
  } catch (err) {
    status.innerHTML = `⚠️ Analysis error: ${err.message}`;
    status.style.color = 'orange';
  }
};  */

const setupMetaAutoRefresh = () => {
  const checkbox = document.getElementById('metaAutoRefresh');
  const intervalField = document.getElementById('metaRefreshInterval');

  if (metaRefreshTimer) clearInterval(metaRefreshTimer);

  if (checkbox.checked) {
    const intervalMin = parseInt(intervalField.value) || 5;
    metaRefreshTimer = setInterval(() => {
      checkMetaStatus();
    }, intervalMin * 60 * 1000);
  }
};

// Connect events
document.getElementById('refreshMetaCheck').addEventListener('click', checkMetaStatus);
document.getElementById('metaAutoRefresh').addEventListener('change', setupMetaAutoRefresh);
document.getElementById('metaRefreshInterval').addEventListener('change', setupMetaAutoRefresh);

// Loading at start
checkMetaStatus();
const levelColors = {
  1: '#f0a202',  // 🔶 orange
  2: '#d94f4f',  // 🔴 red
  3: '#7e1f86'   // 🔥 violet
};

const loadMultiTimeline = async () => {
  const interval = document.getElementById('multiInterval').value;
  const minutes = parseInt(document.getElementById('multiMinutes').value);
  const status = document.getElementById('multiStatus');
  const chartCanvas = document.getElementById('multiTimelineChart');

  status.textContent = '⏳ Loading multianomalies...';

  try {
    const res = await fetch(`${backendUrl}/api/multianomaly_timeline?interval=${interval}&minutes=${minutes}`);
    const data = await res.json();

    if (data.error) throw new Error(data.error);

    let labels = data.timeline.map(e => e.time);
    let levels = data.timeline.map(e => e.level);
    let tooltips = data.timeline.map(e => `Types: ${e.types.join(', ')}`);
    let bgColors = levels.map(lvl => levelColors[lvl]);

    // If there are no multi-anomalies, we create a stub
    if (labels.length === 0) {
      labels = ['—'];
      levels = [0];
      tooltips = ['No multi-anomalies'];
      bgColors = ['#2ecc71']; // green "clear"
    }

    if (window.multiAnomalyChart) window.multiAnomalyChart.destroy();

    const ctx = chartCanvas.getContext('2d');
    window.multiAnomalyChart = new Chart(ctx, {
      type: 'bar',
      data: {
        labels,
        datasets: [{
          label: 'Multianomaly level',
          data: levels,
          backgroundColor: bgColors
        }]
      },
      options: {
        responsive: true,
        scales: {
          y: {
            beginAtZero: true,
            stepSize: 1,
            max: 3,
            title: { display: true, text: 'Level' }
          }
        },
        plugins: {
          tooltip: {
            callbacks: {
              label: function (ctx) {
                return tooltips[ctx.dataIndex];
              }
            }
          }
        }
      }
    });

    if (data.timeline.length === 0) {
      status.textContent = '✅ No multi-anomalies detected';
    } else {
      status.textContent = `✅ Found${data.timeline.length} multi-anomalies`;
    }
  } catch (err) {
    status.textContent = `⚠️ Error loading data: ${err.message}`;
  }
};
document.getElementById('loadMultiTimeline').addEventListener('click', loadMultiTimeline);

async function loadMultiAnomalyLog() {
  const limit = parseInt(document.getElementById("logLimit").value);
  const onlyUnescalated = document.getElementById("logOnlyUnescalated").checked;
  const status = document.getElementById("logStatus");
  const container = document.getElementById("multiLogTableContainer");

  status.textContent = "⏳ Loading log...";
  container.innerHTML = "";

  try {
    const res = await fetch(`${backendUrl}/api/multianomalies_log?limit=${limit}&only_unescalated=${onlyUnescalated}`);
    const data = await res.json();

    if (data.error) throw new Error(data.error);

    if (data.items.length === 0) {
      status.textContent = "✅ No multi-anomalies found for filter conditions";
      return;
    }

    const table = document.createElement("table");
    table.innerHTML = `
      <thead>
        <tr>
          <th>Time</th>
          <th>Types</th>
          <th>Level</th>
          <th>Escalated</th>
        </tr>
      </thead>
      <tbody>
  ${data.items.map(item => `
    <tr>
      <td>${item.time}</td>
      <td>${item.types.join(", ")}</td>
      <td>${item.level}</td>
      <td>
        ${item.escalated
          ? "✅"
          : `<button onclick="escalateAnomaly('${item.time}')">🚨 Escalate</button>`}
      </td>
    </tr>
  `).join("")}
</tbody>

    `;
    container.appendChild(table);

    status.textContent = `✅ Shown ${data.count} events`;
  } catch (err) {
    status.textContent = `⚠️ Error: ${err.message}`;
  }
}
document.getElementById("loadMultiLog").addEventListener("click", loadMultiAnomalyLog);

async function escalateAnomaly(time) {
  if (!confirm(`Confirm event escalation: ${time}?`)) return;

  try {
    const res = await fetch(`${backendUrl}/api/escalate_multianomaly`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ time })
    });
    const data = await res.json();

    if (data.error) {
      alert("⚠️ Error: " + data.error);
    } else {
      alert("✅ Events escalated");
      loadMultiAnomalyLog(); // update table
    }
  } catch (err) {
    alert("⚠️ Request error: " + err.message);
  }
}
window.escalateAnomaly = escalateAnomaly;
