import * as translate from './translate_tls.js'
import { backendUrl } from './config.js'
let lastHttpEvents = [];
let sortFieldHTTP = null;
let sortAscHTTP = true;
let chartHTTP;
let lastSummary = null;
let hasRecentEventsHTTP = false;

const byIdHTTP = (id) => document.getElementById(id);

const tr = (key) => {
  const lang = localStorage.getItem('lang') || 'ru';
  return translate.translations[lang]?.[key] || key;
};
const applyLanguage = (lang) => {
  const dict = translate.translations[lang] || translate.translations['ru'];
  document.querySelectorAll('[data-i18n]').forEach(el => {
    const key = el.getAttribute('data-i18n');
    if (dict[key]) el.textContent = dict[key];
  });
  localStorage.setItem('lang', lang);
  if (lastSummary) {
    showSummaryHTTP(lastSummary.total, lastSummary.anomalies, lastSummary.visible);
  }
};

const initLanguage = () => {
  const lang = localStorage.getItem('lang') || 'ru';
  const select = byIdHTTP('langSelectHTTP');
  if (select) select.value = lang;
  applyLanguage(lang);
  if (select) {
    select.addEventListener('change', (e) => {
      applyLanguage(e.target.value);
    });
  }
};
const saveHttpState = () => {
  localStorage.setItem('limitHTTP', byIdHTTP('limitInputHTTP').value);
  localStorage.setItem('offsetHTTP', byIdHTTP('offsetInputHTTP').value);
  localStorage.setItem('anomalyOnlyHTTP', byIdHTTP('anomalyOnlyCheckboxHTTP').checked);
  localStorage.setItem('intervalHTTP', byIdHTTP('intervalSelectHTTP').value);
};
const LoadHttpState = () => {
  if (localStorage.getItem('limitHTTP')) byIdHTTP('limitInputHTTP').value = localStorage.getItem('limitHTTP');
  if (localStorage.getItem('offsetHTTP')) byIdHTTP('offsetInputHTTP').value = localStorage.getItem('offsetHTTP');
  if (localStorage.getItem('anomalyOnlyHTTP')) byIdHTTP('anomalyOnlyCheckboxHTTP').checked = localStorage.getItem('anomalyOnlyHTTP') === 'true';
  if (localStorage.getItem('intervalHTTP')) byIdHTTP('intervalSelectHTTP').value = localStorage.getItem('intervalHTTP');
};

const analyzeManualHTTP = async () => {
  const input = byIdHTTP('jsonInputHTTP').value;
  const errorBox = byIdHTTP('errorHTTP');
  const resultBox = byIdHTTP('resultHTTP');
  errorBox.textContent = '';
  resultBox.innerHTML = '';

  let events;
  try {
    events = JSON.parse(input);
    if (!Array.isArray(events)) throw new Error('Expected array of objects');
  } catch (err) {
    errorBox.textContent = 'Invalid JSON: ' + err.message;
    return;
  }

  try {
    const res = await fetch(`${backendUrl}/ai/analyze/http`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ events })
    });
    const data = await res.json();

    if (data.error) {
      errorBox.textContent = 'Error: ' + data.error;
    } else {
      resultBox.innerHTML = 
        `<p><strong>Total events:</strong> ${data.total}</p>
        <p><strong>Anomalies:</strong> ${data.anomaly_count}</p>
        <pre>${JSON.stringify(data.anomalies, null, 2)}</pre>`;
    }
  } catch (err) {
    errorBox.textContent = 'Request error: ' + err.message;
  }
};

const analyzeHttpFromRedis = async () => {
  const limit = parseInt(byIdHTTP('limitInputHTTP').value) || 100;
  const offset = parseInt(byIdHTTP('offsetInputHTTP').value) || 0;
  const onlyAnomalies = byIdHTTP('anomalyOnlyCheckboxHTTP').checked;

  try {
    const res = await fetch(`${backendUrl}/api/analyze/http?limit=${limit}&offset=${offset}&only_anomalies=${onlyAnomalies}`);
    const data = await res.json();

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

    lastHttpEvents = data.events;
    hasRecentEventsHTTP = data.events.length > 0;
    sortFieldHTTP = null;
    sortAscHTTP = true;

    byIdHTTP('http-results').innerHTML = '';
    byIdHTTP('detailsBoxHTTP').innerHTML = '';

    const visibleCount = onlyAnomalies ? limit : data.events.length;
    showSummaryHTTP(data.total, data.anomaly_count, visibleCount);
    renderHttpEvents(data.events);
  } catch (err) {
    byIdHTTP('http-results').innerHTML = `<tr><td colspan="8" class="error">Error: ${err.message}</td></tr>`;
  }
};

const showSummaryHTTP = (total, anomalies, visible) => {
  const percent = ((anomalies / (visible || 1)) * 100).toFixed(2);
  byIdHTTP('summaryBoxHTTP').innerHTML = 
    `<p><strong>Total in Redis:</strong> ${total} events</p>
    <p><strong>In sample:</strong> ${visible}, found anomalies: ${anomalies} (${percent}%)</p>`;
};

const renderHttpEvents = (events) => {
  const tbody = byIdHTTP('http-results');
  tbody.innerHTML = '';

  events.forEach(({ index, src_ip, dst_ip, anomaly, full }) => {
    const {
      src_port,
      dest_port,
      proto,
      http = {}
    } = full;

    const hostname = http.hostname || '';
    const http_content_type = http.http_content_type || '';


    const row = document.createElement('tr');
    row.className = anomaly ? 'anomaly' : 'normal';

    // Utility for creating a cell with safe text
    const createCell = (text) => {
      const td = document.createElement('td');
      td.textContent = text ?? '';
      return td;
    };

    // Adding cells with safe content
    row.appendChild(createCell(index + 1));
    row.appendChild(createCell(`${src_ip}:${src_port || ''}`));
    row.appendChild(createCell(`${dst_ip}:${dest_port || ''}`));
    row.appendChild(createCell(proto || ''));
    row.appendChild(createCell(hostname));
    row.appendChild(createCell(http_content_type));
    row.appendChild(createCell(anomaly ? 'Yes🚨' : 'No ✅'));

    // Details button
    const detailsButton = document.createElement('button');
    detailsButton.textContent = '🔍';
    detailsButton.style.fontSize = '12px';
    detailsButton.style.padding = '2px 6px';
    detailsButton.onclick = () => showDetailsHTTP(full);
    const detailsTd = document.createElement('td');
    detailsTd.appendChild(detailsButton);
    row.appendChild(detailsTd);

    // "Copy rule" button
    const copyButton = document.createElement('button');
    copyButton.textContent = '⚡';
    copyButton.style.fontSize = '12px';
    copyButton.style.padding = '2px 6px';
    copyButton.onclick = () => copySuricataRuleHTTP(src_ip);
    const copyTd = document.createElement('td');
    copyTd.appendChild(copyButton);
    row.appendChild(copyTd);

    tbody.appendChild(row);
  });
};


window.showDetailsHTTP = (event) => {
  byIdHTTP('detailsBoxHTTP').innerHTML = `<h3>Event details:</h3><pre>${JSON.stringify(event, null, 2)}</pre>`;
  byIdHTTP('detailsBoxHTTP').scrollIntoView({ behavior: 'smooth' });
};

const exportAnomaliesHTTP = (format) => {
  const anomalies = lastHttpEvents.filter(e => e.anomaly);
  if (anomalies.length === 0) return alert('No anomalies for export');

  if (format === 'csv') {
    const headers = Object.keys(anomalies[0]);
    const rows = anomalies.map(e => headers.map(h => JSON.stringify(e[h] ?? '')).join(','));
    const csv = [headers.join(','), ...rows].join('\n');
    const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = 'http_anomalies.csv';
    link.click();
  } else {
    const blob = new Blob([JSON.stringify(anomalies, null, 2)], { type: 'application/json' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = 'http_anomalies.json';
    link.click();
  }
};

// JS function for generating a rule and showing a modal window
window.copySuricataRuleHTTP = (ip) => {
  const rule = `drop ip [${ip}] any -> any any (msg:"Blocked malicious IP ${ip}"; sid:999001; rev:1;)`;
  
  // Insert a rule into a modal window
  const modal = document.getElementById('suricataModal');
  const ruleBox = document.getElementById('suricataRule');
  
  if (modal && ruleBox) {
    ruleBox.textContent = rule;
    modal.style.display = 'block';
  } else {
    alert('Error: Failed to display rule.');
  }
};


byIdHTTP('analyzeManualHTTP').addEventListener('click', analyzeManualHTTP);
byIdHTTP('analyzeRedisHTTP').addEventListener('click', analyzeHttpFromRedis);
byIdHTTP('exportCSVHTTP').addEventListener('click', () => exportAnomaliesHTTP('csv'));
byIdHTTP('exportJSONHTTP').addEventListener('click', () => exportAnomaliesHTTP('json'));

// Charts
const loadTimelineChartHTTP = async () => {
  console.log("start");
  const interval = byIdHTTP('intervalSelectHTTP').value;
  const limit = parseInt(byIdHTTP('limitInputHTTP').value) || 100;
  const offset = parseInt(byIdHTTP('offsetInputHTTP').value) || 0;
  const url = `${backendUrl}/api/analyze_http_timeline?interval=${interval}&limit=${limit}&offset=${offset}`;

  try {
    const res = await fetch(url);
    const data = await res.json();
    console.log("start mapping");
    const labels = data.timeline.map(t => t.time);
    const values = data.timeline.map(t => t.anomalies);
    console.log("end mapping");
    if (chartHTTP) chartHTTP.destroy();
    const ctx = byIdHTTP('timelineChartHTTP').getContext('2d');
    console.log("start charting");
    chartHTTP = new Chart(ctx, {
      type: 'line',
      data: {
        labels,
        datasets: [{
          label: `Anomalies (${interval})`,
          data: values,
          fill: false,
          tension: 0.2
        }]
      },
      options: {
        responsive: true,
        scales: { y: { beginAtZero: true } }
      }
    });
  } catch (err) {
    alert('Error loading chart: ' + err.message);
  }
};

const loadCompareChartHTTP = async () => {
  const from = parseInt(byIdHTTP('fromHourHTTP').value);
  const to = parseInt(byIdHTTP('toHourHTTP').value);
  const url = `${backendUrl}/api/anomaly_http_compare?from_hour=${from}&to_hour=${to}`;

  try {
    const res = await fetch(url);
    const data = await res.json();
    if (data.error) throw new Error(data.error);

    const ctx = byIdHTTP('httpCompareChart').getContext('2d');
    if (window.compareChartObj) window.compareChartObj.destroy();

    window.compareChartObj = new Chart(ctx, {
      type: 'bar',
      data: {
        labels: ['Today', 'Yesterday'],
        datasets: [{
          label: `Anomalies (${data.interval})`,
          data: [data.today.anomalies, data.yesterday.anomalies],
          backgroundColor: ['#e19435', '#0e56ff']
        }]
      },
      options: {
        scales: { y: { beginAtZero: true } }
      }
    });
  } catch (err) {
    alert('Comparison error: ' + err.message);
  }
};

const loadHourlyCompareChartHTTP = async () => {
  const from = parseInt(byIdHTTP('fromHourChartHTTP').value);
  const to = parseInt(byIdHTTP('toHourChartHTTP').value);
  const url = `${backendUrl}/api/anomaly_http_compare_timeline?from_hour=${from}&to_hour=${to}`;

  try {
    const res = await fetch(url);
    const data = await res.json();
    if (data.error) throw new Error(data.error);

    const labels = data.timeline.map(t => t.hour);
    const todayData = data.timeline.map(t => t.today);
    const yesterdayData = data.timeline.map(t => t.yesterday);

    const ctx = byIdHTTP('httpHourlyCompareChart').getContext('2d');
    if (window.hourlyCompareChartObj) window.hourlyCompareChartObj.destroy();

    window.hourlyCompareChartObj = new Chart(ctx, {
      type: 'bar',
      data: {
        labels,
        datasets: [
          {
            label: 'Today',
            data: todayData,
            backgroundColor: '#e19435'
          },
          {
            label: 'Yesterday',
            data: yesterdayData,
            backgroundColor: '#0e56ff'
          }
        ]
      },
      options: {
        responsive: true,
        scales: { y: { beginAtZero: true } }
      }
    });
  } catch (err) {
    alert('Error building chart: ' + err.message);
  }
};

byIdHTTP('timelineBtnHTTP').addEventListener('click', loadTimelineChartHTTP);
byIdHTTP('compareBtnHTTP').addEventListener('click', loadCompareChartHTTP);
byIdHTTP('hourlyCompareBtnHTTP').addEventListener('click', loadHourlyCompareChartHTTP);

let autoRefreshIntervalHTTP = null;

const setupAutoRefreshHTTP = () => {
  const checkbox = byIdHTTP('autoRefreshHTTP');
  if (!checkbox) return;

  if (autoRefreshIntervalHTTP) clearInterval(autoRefreshIntervalHTTP);

  if (checkbox.checked) {
    autoRefreshIntervalHTTP = setInterval(() => {
      if (checkbox.checked  && hasRecentEventsHTTP) {
        analyzeHttpFromRedis();
      }
    }, 120000); // 120 sec
  }
};

const autoCheckbox = byIdHTTP('autoRefresh');
if (autoCheckbox) {
  autoCheckbox.addEventListener('change', setupAutoRefreshHTTP);
}

const sortHTTPTableBy = (field) => {
  if (sortFieldHTTP === field) {
    sortAscHTTP = !sortAscHTTP;
  } else {
    sortFieldHTTP = field;
    sortAscHTTP = true;
  }

  const getValue = (obj) => {
    return (
      obj[field] ??
      obj.http?.[field] ??
      obj.full?.[field] ??
      obj.full?.http?.[field] ??
      ''
    );
  };

  const isNumeric = (val) =>
    typeof val === 'number' || (!isNaN(val) && val !== '');

  lastHttpEvents.sort((a, b) => {
    const valA = getValue(a);
    const valB = getValue(b);

    // Special sorting by boolean values ​​(eg anomaly)
    if (typeof valA === 'boolean' && typeof valB === 'boolean') {
      return sortAscHTTP
        ? (valA === valB ? 0 : valA ? -1 : 1)
        : (valA === valB ? 0 : valA ? 1 : -1);
    }

    // If both values ​​are numeric, sort as numbers
    if (isNumeric(valA) && isNumeric(valB)) {
      return sortAscHTTP ? valA - valB : valB - valA;
    }

    // Otherwise, we sort as strings
    const strA = String(valA).toLowerCase();
    const strB = String(valB).toLowerCase();

    if (strA < strB) return sortAscHTTP ? -1 : 1;
    if (strA > strB) return sortAscHTTP ? 1 : -1;
    return 0;
  });

  renderHttpEvents(lastHttpEvents);
};



document.querySelectorAll('th[data-sort]').forEach(th => {
  th.addEventListener('click', () => sortHTTPTableBy(th.dataset.sort));
});
LoadHttpState();
setupAutoRefreshHTTP();
// initLanguageHTTP(); // can be uncommented if a challenge is needed
