// PhishProtect Extension — Techniques Page Logic
// Loads techniques.json, renders grid/tree/detail, handles policy toggles

(function () {
  'use strict';

  var techData = null;
  var breadcrumb = [];
  var policySettings = {};

  // Load data
  var jsonUrl = typeof chrome !== 'undefined' && chrome.runtime
    ? chrome.runtime.getURL('data/techniques.json')
    : 'data/techniques.json';

  fetch(jsonUrl)
    .then(function (r) { return r.json(); })
    .then(function (data) {
      techData = data;
      loadPolicySettings(function () {
        renderStats(data.stats);
        renderGrid(data.categories);
        renderTree(data.categories);
        handleHash();
        window.addEventListener('hashchange', handleHash);
      });
    })
    .catch(function (err) {
      console.error('Failed to load techniques data:', err);
    });

  // Policy settings via chrome.storage
  function loadPolicySettings(cb) {
    if (typeof chrome !== 'undefined' && chrome.storage && chrome.storage.local) {
      chrome.storage.local.get('policySettings', function (result) {
        policySettings = result.policySettings || {};
        cb();
      });
    } else {
      cb();
    }
  }

  function savePolicySetting(key, value) {
    policySettings[key] = value;
    if (typeof chrome !== 'undefined' && chrome.storage && chrome.storage.local) {
      chrome.storage.local.set({ policySettings: policySettings });
    }
  }

  function isDetectorEnabled(detectorId) {
    var key = 'detectors.' + detectorId + '.enabled';
    return policySettings[key] !== false; // default enabled
  }

  // Stats
  function renderStats(stats) {
    var el = document.getElementById('ext-stats');
    if (el) {
      el.innerHTML =
        '<div class="ext-stat-box"><span class="ext-stat-num cov-yes">' + stats.coverage.yes + '</span><span class="ext-stat-label">Fully Covered</span></div>' +
        '<div class="ext-stat-box"><span class="ext-stat-num cov-partial">' + stats.coverage.partial + '</span><span class="ext-stat-label">Partial</span></div>' +
        '<div class="ext-stat-box"><span class="ext-stat-num cov-no">' + stats.coverage.no + '</span><span class="ext-stat-label">Not Addressable</span></div>';
    }
    var hdr = document.getElementById('header-stats');
    if (hdr) {
      hdr.innerHTML = '<span><strong>' + stats.totalTechniques + '</strong> techniques</span><span><strong>' + stats.totalDetectors + '</strong> detectors</span>';
    }
  }

  // View toggle
  document.querySelectorAll('.ext-view-btn').forEach(function (btn) {
    btn.addEventListener('click', function () {
      var view = btn.getAttribute('data-view');
      document.querySelectorAll('.ext-view-btn').forEach(function (b) { b.classList.remove('active'); });
      btn.classList.add('active');
      document.querySelectorAll('.ext-panel').forEach(function (p) { p.classList.remove('active'); });
      var target = document.getElementById('ext-' + view);
      if (target) target.classList.add('active');
    });
  });

  // Search
  var searchInput = document.getElementById('ext-search');
  if (searchInput) {
    searchInput.addEventListener('input', function () {
      var q = searchInput.value.toLowerCase().trim();
      filterTechniques(q);
    });
  }

  function filterTechniques(query) {
    if (!techData) return;
    var gridEl = document.getElementById('ext-grid');
    if (gridEl && breadcrumb.length === 0) {
      if (query) {
        var filtered = techData.categories.filter(function (cat) {
          return catContains(cat, query);
        });
        renderGridCards(filtered, gridEl);
      } else {
        renderGridCards(techData.categories, gridEl);
      }
    }
    var treeEl = document.getElementById('ext-tree');
    if (treeEl) filterTreeNodes(treeEl, query);
  }

  function catContains(cat, q) {
    if (cat.name.toLowerCase().includes(q)) return true;
    for (var i = 0; i < (cat.techniques || []).length; i++) {
      if (cat.techniques[i].title.toLowerCase().includes(q)) return true;
    }
    for (var j = 0; j < (cat.children || []).length; j++) {
      if (catContains(cat.children[j], q)) return true;
    }
    return false;
  }

  function filterTreeNodes(container, query) {
    var nodes = container.querySelectorAll('.ext-tree-node');
    var leaves = container.querySelectorAll('.ext-tree-leaf');
    if (!query) {
      nodes.forEach(function (n) { n.style.display = ''; });
      leaves.forEach(function (l) { l.style.display = ''; });
      return;
    }
    leaves.forEach(function (l) {
      var name = (l.getAttribute('data-name') || '').toLowerCase();
      l.style.display = name.includes(query) ? '' : 'none';
    });
    Array.from(nodes).reverse().forEach(function (n) {
      var hasVisible = n.querySelector('.ext-tree-leaf:not([style*="display: none"]), .ext-tree-node:not([style*="display: none"])');
      n.style.display = hasVisible ? '' : 'none';
      if (hasVisible && query) n.classList.add('expanded');
    });
  }

  // Grid
  function renderGrid(categories) {
    var el = document.getElementById('ext-grid');
    if (!el) return;
    breadcrumb = [];
    renderGridCards(categories, el);
  }

  function renderGridCards(items, container) {
    var html = '';

    if (breadcrumb.length > 0) {
      html += '<div class="ext-breadcrumb">';
      html += '<button class="ext-bc-item" data-bc="-1">All</button>';
      for (var b = 0; b < breadcrumb.length; b++) {
        html += '<span class="ext-bc-sep">&rsaquo;</span>';
        html += '<button class="ext-bc-item" data-bc="' + b + '">' + esc(breadcrumb[b].name) + '</button>';
      }
      html += '</div>';
    }

    html += '<div class="ext-card-grid">';
    for (var i = 0; i < items.length; i++) {
      var it = items[i];
      if (it.id && it.id.startsWith('t-')) {
        html += '<div class="ext-card" data-tid="' + it.id + '">';
        html += '<div class="ext-card-name">' + esc(it.title) + '</div>';
        html += '<div class="ext-card-count"><span class="ext-cov-pill cov-' + it.coverage + '">' + it.coverage + '</span></div>';
        html += '</div>';
      } else {
        var count = countTechs(it);
        var cov = covStats(it);
        var total = cov.yes + cov.partial + cov.no;
        var yW = total > 0 ? (cov.yes / total * 100) : 0;
        var pW = total > 0 ? (cov.partial / total * 100) : 0;
        html += '<div class="ext-card" data-cid="' + it.id + '">';
        html += '<div class="ext-card-name">' + esc(it.name) + '</div>';
        html += '<div class="ext-card-count">' + count + ' technique' + (count !== 1 ? 's' : '') + '</div>';
        html += '<div class="ext-cov-bar">';
        html += '<div class="ext-cov-seg cov-yes" style="width:' + yW + '%"></div>';
        html += '<div class="ext-cov-seg cov-partial" style="width:' + pW + '%"></div>';
        html += '<div class="ext-cov-seg cov-no" style="width:' + (100 - yW - pW) + '%"></div>';
        html += '</div></div>';
      }
    }
    html += '</div>';
    if (items.length === 0) html += '<div class="ext-no-results">No matching techniques found.</div>';

    container.innerHTML = html;

    container.querySelectorAll('.ext-card[data-cid]').forEach(function (c) {
      c.addEventListener('click', function () {
        var node = findCat(techData.categories, c.getAttribute('data-cid'));
        if (!node) return;
        breadcrumb.push(node);
        renderGridCards(node.children.concat(node.techniques || []), container);
      });
    });
    container.querySelectorAll('.ext-card[data-tid]').forEach(function (c) {
      c.addEventListener('click', function () { showDetail(c.getAttribute('data-tid')); });
    });
    container.querySelectorAll('.ext-bc-item').forEach(function (btn) {
      btn.addEventListener('click', function () {
        var idx = parseInt(btn.getAttribute('data-bc'), 10);
        if (idx === -1) { breadcrumb = []; renderGridCards(techData.categories, container); }
        else { breadcrumb = breadcrumb.slice(0, idx + 1); var n = breadcrumb[breadcrumb.length - 1]; renderGridCards(n.children.concat(n.techniques || []), container); }
      });
    });
  }

  // Tree
  function renderTree(categories) {
    var el = document.getElementById('ext-tree');
    if (!el) return;
    el.innerHTML = '<div class="ext-tree">' + buildTree(categories) + '</div>';
    el.querySelectorAll('.ext-tree-header').forEach(function (h) {
      h.addEventListener('click', function () { h.parentElement.classList.toggle('expanded'); });
    });
    el.querySelectorAll('.ext-tree-leaf').forEach(function (l) {
      l.addEventListener('click', function () { showDetail(l.getAttribute('data-tid')); });
    });
  }

  function buildTree(nodes) {
    var html = '';
    for (var i = 0; i < nodes.length; i++) {
      var n = nodes[i];
      var has = (n.children && n.children.length > 0) || (n.techniques && n.techniques.length > 0);
      html += '<div class="ext-tree-node" data-name="' + escA(n.name) + '">';
      html += '<div class="ext-tree-header"><span class="ext-tree-chevron">' + (has ? '\u25B8' : '') + '</span>';
      html += '<span class="ext-tree-name">' + esc(n.name) + '</span>';
      html += '<span class="ext-cov-pill cov-' + n.coverage + '">' + n.coverage + '</span></div>';
      if (has) {
        html += '<div class="ext-tree-children">';
        if (n.children.length > 0) html += buildTree(n.children);
        for (var j = 0; j < (n.techniques || []).length; j++) {
          var t = n.techniques[j];
          html += '<div class="ext-tree-leaf" data-tid="' + t.id + '" data-name="' + escA(t.title) + '">';
          html += '<span class="ext-cov-pill cov-' + t.coverage + '">' + t.coverage + '</span> ' + esc(t.title) + '</div>';
        }
        html += '</div>';
      }
      html += '</div>';
    }
    return html;
  }

  // Detail panel
  var detailPanel = document.getElementById('ext-detail');
  var detailOverlay = document.getElementById('ext-detail-overlay');
  var detailClose = document.getElementById('ext-detail-close');

  if (detailClose) detailClose.addEventListener('click', closeDetail);
  if (detailOverlay) detailOverlay.addEventListener('click', closeDetail);

  function closeDetail() {
    if (detailPanel) detailPanel.classList.remove('active');
    if (detailOverlay) detailOverlay.classList.remove('active');
    if (window.location.hash.startsWith('#technique/') || window.location.hash.startsWith('#detector/')) {
      history.replaceState(null, '', window.location.pathname);
    }
  }

  function showDetail(techniqueId) {
    if (!techData || !detailPanel) return;
    var info = techData.techniqueIndex[techniqueId];
    if (!info) return;
    var tech = findTech(techData.categories, techniqueId);
    if (!tech) return;

    var scroll = document.getElementById('ext-detail-scroll');
    if (!scroll) return;

    var html = '<div class="ext-detail-title">' + esc(tech.title) + '</div>';
    html += '<div class="ext-detail-meta">';
    html += '<span class="ext-cov-pill cov-' + tech.coverage + '">' + tech.coverage + '</span>';
    if (tech.mitreTactic) {
      html += '<span class="ext-detail-badge mitre">MITRE: ' + esc(tech.mitreTactic);
      if (tech.mitreId) html += ' / ' + esc(tech.mitreId);
      html += '</span>';
    }
    html += '</div>';

    if (info.path && info.path.length > 0) {
      html += '<div class="ext-detail-section"><div class="ext-detail-section-title">Category Path</div>';
      html += '<p>' + info.path.map(esc).join(' &rsaquo; ') + '</p></div>';
    }
    if (tech.description) {
      html += '<div class="ext-detail-section"><div class="ext-detail-section-title">Description</div>';
      html += '<p>' + esc(tech.description) + '</p></div>';
    }
    if (tech.capabilities && tech.capabilities.length > 0) {
      html += '<div class="ext-detail-section"><div class="ext-detail-section-title">Capabilities</div><ul class="ext-detail-list">';
      tech.capabilities.forEach(function (c) { html += '<li>' + esc(c) + '</li>'; });
      html += '</ul></div>';
    }
    if (tech.technologies && tech.technologies.length > 0) {
      html += '<div class="ext-detail-section"><div class="ext-detail-section-title">Technologies</div><ul class="ext-detail-list">';
      tech.technologies.forEach(function (t) { html += '<li>' + esc(t) + '</li>'; });
      html += '</ul></div>';
    }
    if (tech.detectors && tech.detectors.length > 0) {
      html += '<div class="ext-detail-section"><div class="ext-detail-section-title">Active Detectors</div>';
      tech.detectors.forEach(function (detId) {
        var det = findDet(detId);
        if (!det) return;
        var enabled = isDetectorEnabled(detId);
        html += '<div class="ext-det-card">';
        html += '<div class="ext-det-header"><span class="ext-det-name">' + esc(det.name) + '</span>';
        html += '<span class="ext-det-sev sev-' + det.severity + '">' + det.severity + '</span></div>';
        html += '<div class="ext-det-desc">' + esc(det.description) + '</div>';
        html += '<div class="ext-toggle-row"><span class="ext-toggle-label">Enabled</span>';
        html += '<label class="ext-toggle"><input type="checkbox" data-detector="' + detId + '"' + (enabled ? ' checked' : '') + '><span class="ext-toggle-slider"></span></label>';
        html += '</div></div>';
      });
      html += '</div>';
    }

    scroll.innerHTML = html;

    // Toggle handlers
    scroll.querySelectorAll('input[data-detector]').forEach(function (inp) {
      inp.addEventListener('change', function () {
        var id = inp.getAttribute('data-detector');
        savePolicySetting('detectors.' + id + '.enabled', inp.checked);
      });
    });

    detailPanel.classList.add('active');
    if (detailOverlay) detailOverlay.classList.add('active');
    history.replaceState(null, '', '#technique/' + techniqueId);
  }

  function showDetectorDetail(detectorId) {
    if (!techData) return;
    var det = findDet(detectorId);
    if (!det) return;
    // Open the first linked technique
    if (det.techniqueIds && det.techniqueIds.length > 0) {
      showDetail(det.techniqueIds[0]);
    }
  }

  // Hash routing
  function handleHash() {
    var hash = window.location.hash;
    if (!hash || !techData) return;
    if (hash.startsWith('#technique/')) {
      showDetail(hash.replace('#technique/', ''));
    } else if (hash.startsWith('#detector/')) {
      showDetectorDetail(hash.replace('#detector/', ''));
    }
  }

  // Helpers
  function findCat(cats, id) {
    for (var i = 0; i < cats.length; i++) {
      if (cats[i].id === id) return cats[i];
      var f = findCat(cats[i].children, id);
      if (f) return f;
    }
    return null;
  }

  function findTech(cats, id) {
    for (var i = 0; i < cats.length; i++) {
      for (var j = 0; j < (cats[i].techniques || []).length; j++) {
        if (cats[i].techniques[j].id === id) return cats[i].techniques[j];
      }
      var f = findTech(cats[i].children, id);
      if (f) return f;
    }
    return null;
  }

  function findDet(id) {
    if (!techData) return null;
    for (var i = 0; i < techData.detectors.length; i++) {
      if (techData.detectors[i].id === id) return techData.detectors[i];
    }
    return null;
  }

  function countTechs(node) {
    var c = (node.techniques || []).length;
    for (var i = 0; i < (node.children || []).length; i++) c += countTechs(node.children[i]);
    return c;
  }

  function covStats(node) {
    var y = 0, p = 0, n = 0;
    (node.techniques || []).forEach(function (t) { if (t.coverage === 'yes') y++; else if (t.coverage === 'partial') p++; else n++; });
    (node.children || []).forEach(function (c) { var s = covStats(c); y += s.yes; p += s.partial; n += s.no; });
    return { yes: y, partial: p, no: n };
  }

  function esc(s) {
    if (!s) return '';
    var d = document.createElement('div');
    d.textContent = s;
    return d.innerHTML;
  }

  function escA(s) { return esc(s).replace(/"/g, '&quot;'); }
})();
