/**
 * Team workload dashboard.
 * Current tab: per-agent widget with section title + ticket table.
 * Performance tab: compact agent rows with resolved counts.
 */
import { getJson } from '/js/core/app-http.js';
import { resolveHost } from '/js/core/app-dom.js';

const EMPTY_API = Object.freeze({ destroy: () => {} });

const resolveContainer = (root) => {
  const host = resolveHost(root);
  if (host instanceof HTMLElement && host.matches('.app-details-container[data-app-component="helpdesk-team"]')) {
    return host;
  }
  return host.querySelector('.app-details-container[data-app-component="helpdesk-team"]');
};

export function initHelpdeskTeam(root = document) {
  const container = resolveContainer(root);
  if (!container) {
    return EMPTY_API;
  }

  const listenerController = new AbortController();
  const requestController = new AbortController();
  const on = (target, type, handler, options = {}) => {
    if (!target || typeof target.addEventListener !== 'function') {
      return;
    }
    target.addEventListener(type, handler, { ...options, signal: listenerController.signal });
  };

  const dataUrl = container.dataset.teamWorkloadUrl;
  const labelQueue = container.dataset.labelQueue || 'Queue';
  const labelTickets = container.dataset.labelTickets || 'Tickets';
  const labelCritical = container.dataset.labelCritical || 'Critical (>48h open)';
  const labelTrendHint = container.dataset.labelTrendHint || 'Trend based on last {days} days';
  const ticketBaseUrl = container.dataset.ticketBaseUrl || '';
  const debitorBaseUrl = container.dataset.debitorBaseUrl || '';
  const labelTrendUp = container.dataset.labelTrendUp || 'Backlog growing';
  const labelTrendDown = container.dataset.labelTrendDown || 'Backlog shrinking';

  const elLoading = document.getElementById('team-loading');
  const elError = document.getElementById('team-error');
  const elEmpty = document.getElementById('team-empty');
  const elContent = document.getElementById('team-content');
  const elCurrentCards = document.getElementById('team-current-cards');
  const elPerformanceCards = document.getElementById('team-performance-cards');
  const elRefresh = container.querySelector('button[name="team-refresh"]');
  const periodSelector = document.getElementById('team-period-selector');

  let currentPeriod = 30;

  function showState(state) {
    if (elLoading) elLoading.hidden = state !== 'loading';
    if (elError) elError.hidden = state !== 'error';
    if (elEmpty) elEmpty.hidden = state !== 'empty';
    if (elContent) elContent.hidden = state !== 'success';
  }

  function h(tag, cls, text) {
    const e = document.createElement(tag);
    if (cls) e.className = cls;
    if (text !== undefined) e.textContent = text;
    return e;
  }

  function initials(name) {
    const parts = name.trim().split(/\s+/);
    if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
    return name.substring(0, 2).toUpperCase();
  }

  function formatDateTime(isoString) {
    if (!isoString) return '—';
    const d = new Date(isoString);
    if (isNaN(d.getTime())) return '—';
    return d.toLocaleDateString(undefined, { day: '2-digit', month: '2-digit', year: 'numeric' });
  }

  /**
   * Build a ticket table row: No (link) | Customer (link) | Description | Last activity
   */
  function buildTicketRow(t) {
    const tr = h('tr', t.critical ? 'helpdesk-team-ticket-critical' : '');

    // Ticket number as link
    const noCell = h('td', 'helpdesk-team-ticket-no');
    if (ticketBaseUrl && t.no) {
      const a = h('a', '', t.no);
      a.href = ticketBaseUrl + encodeURIComponent(t.no);
      noCell.appendChild(a);
    } else {
      noCell.textContent = t.no || '—';
    }
    tr.appendChild(noCell);

    // Customer name (link to debitor when customer_no available)
    const customerCell = h('td', 'helpdesk-team-ticket-customer');
    const customerDisplay = t.customer_name || t.customer_no || '—';
    if (debitorBaseUrl && t.customer_no) {
      const a = h('a', '', customerDisplay);
      a.href = debitorBaseUrl + encodeURIComponent(t.customer_no);
      customerCell.appendChild(a);
    } else {
      customerCell.textContent = customerDisplay;
    }
    tr.appendChild(customerCell);

    // Description (ellipsis)
    tr.appendChild(h('td', 'helpdesk-team-ticket-desc', t.description || '—'));

    // Category
    tr.appendChild(h('td', '', t.category || '—'));

    // Last activity date
    tr.appendChild(h('td', 'helpdesk-team-ticket-date', formatDateTime(t.last_activity)));

    return tr;
  }

  /**
   * Build a section widget for one agent — mirrors debitor dashboard section pattern.
   */
  function buildAgentWidget(m, isQueue) {
    const section = h('section', 'helpdesk-team-widget');

    // Section title: "MM  Name   (count)" with line — same as helpdesk-support-section-title
    const title = h('h3', 'helpdesk-support-section-title');
    const name = isQueue ? labelQueue : m.display_name;
    const count = String(m.open_tickets);

    if (!isQueue) {
      const avatar = h('span', 'helpdesk-team-avatar-inline', initials(m.display_name));
      title.appendChild(avatar);
    }
    title.appendChild(document.createTextNode(name));

    title.appendChild(h('span', 'helpdesk-team-title-count', count));

    // Trend delta: ↑3 (growing) or ↓2 (shrinking)
    const delta = m.trend_delta ?? 0;
    if (delta !== 0) {
      const arrow = delta > 0 ? '↑' : '↓';
      const cls = delta > 0 ? 'helpdesk-team-trend-up' : 'helpdesk-team-trend-down';
      const tooltip = delta > 0 ? labelTrendUp : labelTrendDown;
      const trendEl = h('span', cls, arrow + Math.abs(delta));
      trendEl.setAttribute('data-tooltip', tooltip);
      trendEl.setAttribute('data-tooltip-pos', 'top');
      trendEl.tabIndex = 0;
      title.appendChild(trendEl);
    }

    section.appendChild(title);

    // Ticket table
    const tickets = m.open_ticket_details || [];
    if (tickets.length > 0) {
      const table = h('table', 'helpdesk-team-ticket-table');

      // Colgroup for consistent column widths across all agent cards
      const colgroup = document.createElement('colgroup');
      colgroup.appendChild(h('col', 'helpdesk-team-col-ticket'));
      colgroup.appendChild(h('col', 'helpdesk-team-col-customer'));
      colgroup.appendChild(h('col', 'helpdesk-team-col-description'));
      colgroup.appendChild(h('col', 'helpdesk-team-col-category'));
      colgroup.appendChild(h('col', 'helpdesk-team-col-activity'));
      table.appendChild(colgroup);

      const thead = h('thead');
      const headRow = h('tr');
      headRow.appendChild(h('th', '', container.dataset.labelTicket || 'Ticket'));
      headRow.appendChild(h('th', '', container.dataset.labelCustomer || 'Customer'));
      headRow.appendChild(h('th', '', container.dataset.labelDescription || 'Description'));
      headRow.appendChild(h('th', '', container.dataset.labelCategory || 'Category'));
      headRow.appendChild(h('th', '', container.dataset.labelLastActivity || 'Last activity'));
      thead.appendChild(headRow);
      table.appendChild(thead);

      const tbody = h('tbody');
      for (const t of tickets) tbody.appendChild(buildTicketRow(t));
      table.appendChild(tbody);
      const scrollWrap = h('div', 'helpdesk-team-table-scroll');
      scrollWrap.appendChild(table);
      section.appendChild(scrollWrap);
    }

    return section;
  }

  function formatResolution(hours) {
    if (hours === null || hours === undefined) return '—';
    if (hours < 1) return '< 1h';
    if (hours < 24) return hours + 'h';
    const d = Math.floor(hours / 24);
    const remainder = hours % 24;
    return remainder > 0 ? d + 'd ' + remainder + 'h' : d + 'd';
  }

  /**
   * Compute Ø/Min/Max from an array of hour values.
   */
  function computeResolution(hours) {
    const valid = hours.filter(h => h !== null && h !== undefined);
    if (valid.length === 0) return { avg: null, min: null, max: null };
    return {
      avg: Math.round(valid.reduce((a, b) => a + b, 0) / valid.length),
      min: Math.min(...valid),
      max: Math.max(...valid),
    };
  }

  /**
   * Build a clickable ranked list (top customers / top categories).
   * Clicking an item filters the resolution times and calls onFilter.
   */
  function buildRankedList(items, label, filterKey, resolvedDetails, onFilter) {
    if (!items || items.length === 0) return null;

    const wrap = h('div', 'helpdesk-team-perf-stat');
    wrap.appendChild(h('span', 'helpdesk-team-perf-stat-label', label));

    const list = h('ol', 'helpdesk-team-perf-ranked');
    let activeItem = null;

    for (const item of items) {
      const li = h('li', 'helpdesk-team-perf-ranked-clickable');

      on(li, 'click', () => {
        if (activeItem === li) {
          activeItem.classList.remove('active');
          activeItem = null;
          onFilter(null);
        } else {
          if (activeItem) activeItem.classList.remove('active');
          li.classList.add('active');
          activeItem = li;

          const filtered = resolvedDetails
            .filter(d => d[filterKey] === item.name)
            .map(d => d.resolution_hours);
          onFilter(computeResolution(filtered));
        }
      });

      li.appendChild(h('span', 'helpdesk-team-perf-ranked-name', item.name));
      li.appendChild(h('span', 'helpdesk-team-perf-ranked-count', String(item.count)));
      list.appendChild(li);
    }
    wrap.appendChild(list);
    return wrap;
  }

  /**
   * Build a performance widget for one agent — card with insights.
   * Clicking a customer or category recalculates resolution times.
   */
  function buildPerformanceWidget(m) {
    const section = h('section', 'helpdesk-team-widget');
    const perf = m.performance || {};
    const resolvedDetails = perf.resolved_details || [];

    // Header: avatar + name + resolved count
    const title = h('h3', 'helpdesk-support-section-title');
    if (m.support_user !== '') {
      title.appendChild(h('span', 'helpdesk-team-avatar-inline', initials(m.display_name)));
    }
    title.appendChild(document.createTextNode(m.support_user === '' ? labelQueue : m.display_name));
    title.appendChild(h('span', 'helpdesk-team-title-count', String(m.resolved_in_period)));
    section.appendChild(title);

    // Stats grid
    const grid = h('div', 'helpdesk-team-perf-grid');

    // Resolution time column — will be updated on filter
    const timeStats = h('div', 'helpdesk-team-perf-stat');
    timeStats.appendChild(h('span', 'helpdesk-team-perf-stat-label', container.dataset.labelResolutionTime || 'Resolution time'));

    const timeList = h('ol', 'helpdesk-team-perf-ranked helpdesk-team-perf-ranked-plain');
    const avgLi = h('li');
    avgLi.appendChild(h('span', 'helpdesk-team-perf-ranked-name', 'Ø'));
    const avgVal = h('span', 'helpdesk-team-perf-ranked-count', formatResolution(perf.avg_resolution_hours));
    avgLi.appendChild(avgVal);
    timeList.appendChild(avgLi);

    const minLi = h('li');
    minLi.appendChild(h('span', 'helpdesk-team-perf-ranked-name', 'Min'));
    const minVal = h('span', 'helpdesk-team-perf-ranked-count', formatResolution(perf.min_resolution_hours));
    minLi.appendChild(minVal);
    timeList.appendChild(minLi);

    const maxLi = h('li');
    maxLi.appendChild(h('span', 'helpdesk-team-perf-ranked-name', 'Max'));
    const maxVal = h('span', 'helpdesk-team-perf-ranked-count', formatResolution(perf.max_resolution_hours));
    maxLi.appendChild(maxVal);
    timeList.appendChild(maxLi);

    timeStats.appendChild(timeList);

    // Callback: update resolution times when a filter is applied or cleared
    function updateResolution(filtered) {
      if (filtered === null) {
        avgVal.textContent = formatResolution(perf.avg_resolution_hours);
        minVal.textContent = formatResolution(perf.min_resolution_hours);
        maxVal.textContent = formatResolution(perf.max_resolution_hours);
        timeStats.classList.remove('helpdesk-team-perf-stat-filtered');
      } else {
        avgVal.textContent = formatResolution(filtered.avg);
        minVal.textContent = formatResolution(filtered.min);
        maxVal.textContent = formatResolution(filtered.max);
        timeStats.classList.add('helpdesk-team-perf-stat-filtered');
      }
    }

    // Top customers (clickable)
    const customersEl = buildRankedList(
      perf.top_customers,
      container.dataset.labelTopCustomers || 'Top customers',
      'customer_name',
      resolvedDetails,
      updateResolution
    );
    if (customersEl) grid.appendChild(customersEl);

    // Top categories (clickable)
    const categoriesEl = buildRankedList(
      perf.top_categories,
      container.dataset.labelTopCategories || 'Top categories',
      'category',
      resolvedDetails,
      updateResolution
    );
    if (categoriesEl) grid.appendChild(categoriesEl);

    // Resolution time last — updates when customer/category is clicked
    grid.appendChild(timeStats);

    section.appendChild(grid);
    return section;
  }

  function renderCurrentTab(members) {
    if (!elCurrentCards) return;
    elCurrentCards.replaceChildren();

    const visible = members.filter(m => m.open_tickets > 0 || m.critical_tickets > 0);
    for (const m of visible) elCurrentCards.appendChild(buildAgentWidget(m, m.support_user === ''));

    // Legend
    const hasCritical = members.some(m => m.critical_tickets > 0);
    const hasTrend = visible.some(m => (m.trend_delta ?? 0) !== 0);
    if (hasCritical || hasTrend) {
      const legend = h('div', 'helpdesk-team-legend');
      if (hasCritical) {
        const item = h('span', 'helpdesk-team-legend-item');
        item.appendChild(h('span', 'helpdesk-team-legend-dot helpdesk-team-legend-dot-warning'));
        item.appendChild(h('span', '', labelCritical));
        legend.appendChild(item);
      }
      if (hasTrend) {
        const hint = labelTrendHint.replace('{days}', String(currentPeriod));
        legend.appendChild(h('span', 'helpdesk-team-legend-item', '↑↓ ' + hint));
      }
      elCurrentCards.appendChild(legend);
    }
  }

  function renderPerformanceTab(members) {
    if (!elPerformanceCards) return;
    elPerformanceCards.replaceChildren();

    const sorted = [...members]
      .filter(m => m.resolved_in_period > 0)
      .sort((a, b) => {
        if (a.support_user === '') return 1;
        if (b.support_user === '') return -1;
        return b.resolved_in_period - a.resolved_in_period;
      });

    for (const m of sorted) elPerformanceCards.appendChild(buildPerformanceWidget(m));
  }

  async function fetchData(refresh = false) {
    showState('loading');

    const params = new URLSearchParams({ periodDays: String(currentPeriod) });
    if (refresh) params.set('refresh', '1');

    try {
      const json = await getJson(`${dataUrl}?${params.toString()}`, {
        signal: requestController.signal,
      });

      if (!json.ok) { showState('error'); return; }
      if (!json.members || json.members.length === 0) { showState('empty'); return; }

      renderCurrentTab(json.members);
      renderPerformanceTab(json.members);
      showState('success');
    } catch (error) {
      if (error instanceof Error && error.name === 'AbortError') {
        return;
      }
      showState('error');
    }
  }

  on(periodSelector, 'change', (e) => {
    const radio = e.target.closest('input[name="team-period"]');
    if (!radio) return;
    const period = parseInt(radio.value, 10);
    if (!period || period === currentPeriod) return;
    currentPeriod = period;
    void fetchData();
  });

  on(elRefresh, 'click', () => void fetchData(true));

  void fetchData();

  return {
    destroy: () => {
      listenerController.abort();
      requestController.abort();
    },
  };
}
