/**
 * Flynn Sessions Page
 *
 * Lists all sessions, allows viewing history and deleting sessions.
 */

function escapeHtml(text) {
  const div = document.createElement('div');
  div.textContent = text;
  return div.innerHTML;
}

let _client = null;
let _el = null;
let _frontendFilter = '';
let _includeInactive = true;

function formatTime(ts) {
  if (!ts || !Number.isFinite(ts)) {return '—';}
  try {
    return new Date(ts).toLocaleString();
  } catch {
    return '—';
  }
}

function formatQueue(config) {
  const queue = config?.queue;
  if (!queue?.mode) {return 'default';}
  const parts = [queue.mode];
  if (typeof queue.debounceMs === 'number') {
    parts.push(`${queue.debounceMs}ms`);
  }
  if (typeof queue.cap === 'number') {
    parts.push(`cap:${queue.cap}`);
  }
  return parts.join(' · ');
}

async function loadSessionList() {
  if (!_client || !_el) {return;}

  const listContainer = _el.querySelector('#sessions-list');
  const detailContainer = _el.querySelector('#session-detail');
  if (detailContainer) {detailContainer.innerHTML = '';}

  try {
    const params = {
      includePersisted: _includeInactive,
      frontend: _frontendFilter || undefined,
    };
    const result = await _client.call('sessions.list', params);
    const sessions = result.sessions ?? [];

    if (sessions.length === 0) {
      listContainer.innerHTML = '<div class="text-center py-12 px-6 text-zinc-500 text-sm">No sessions found</div>';
      return;
    }

    let html = `
      <div class="overflow-x-auto">
      <table class="w-full text-sm">
        <thead>
          <tr>
            <th class="text-left px-3 py-2 text-xs font-medium text-zinc-400 uppercase tracking-wide border-b border-zinc-800">Session ID</th>
            <th class="text-left px-3 py-2 text-xs font-medium text-zinc-400 uppercase tracking-wide border-b border-zinc-800">Frontend</th>
            <th class="text-left px-3 py-2 text-xs font-medium text-zinc-400 uppercase tracking-wide border-b border-zinc-800">Messages</th>
            <th class="text-left px-3 py-2 text-xs font-medium text-zinc-400 uppercase tracking-wide border-b border-zinc-800">Model</th>
            <th class="text-left px-3 py-2 text-xs font-medium text-zinc-400 uppercase tracking-wide border-b border-zinc-800">Queue</th>
            <th class="text-left px-3 py-2 text-xs font-medium text-zinc-400 uppercase tracking-wide border-b border-zinc-800">Last Activity</th>
            <th class="text-left px-3 py-2 text-xs font-medium text-zinc-400 uppercase tracking-wide border-b border-zinc-800">Actions</th>
          </tr>
        </thead>
        <tbody>
    `;

    for (const s of sessions) {
      html += `
        <tr class="hover:bg-zinc-800/50">
          <td class="px-3 py-2 text-zinc-50 border-b border-zinc-800/50"><a href="#" class="text-blue-500 hover:underline session-view-link" data-id="${escapeHtml(s.id)}">${escapeHtml(s.id)}</a></td>
          <td class="px-3 py-2 text-zinc-50 border-b border-zinc-800/50">${escapeHtml(s.frontend ?? (String(s.id).split(':')[0] || 'unknown'))}</td>
          <td class="px-3 py-2 text-zinc-50 border-b border-zinc-800/50">${s.messageCount ?? 0}</td>
          <td class="px-3 py-2 text-zinc-50 border-b border-zinc-800/50">${escapeHtml(s.config?.modelTier ?? 'default')}</td>
          <td class="px-3 py-2 text-zinc-50 border-b border-zinc-800/50">${escapeHtml(formatQueue(s.config))}</td>
          <td class="px-3 py-2 text-zinc-50 border-b border-zinc-800/50">${escapeHtml(formatTime(s.lastMessageAt))}</td>
          <td class="px-3 py-2 text-zinc-50 border-b border-zinc-800/50">
            <div class="flex gap-1.5">
              <button class="px-2.5 py-1 text-xs font-medium rounded-md border border-zinc-700 bg-zinc-800 text-zinc-200 hover:bg-zinc-700 transition-colors session-view-btn" data-id="${escapeHtml(s.id)}">View</button>
              <button class="px-2.5 py-1 text-xs font-medium rounded-md bg-red-500/15 text-red-500 border border-red-500/30 hover:bg-red-500 hover:text-white transition-colors session-delete-btn" data-id="${escapeHtml(s.id)}">Delete</button>
            </div>
          </td>
        </tr>
      `;
    }

    html += '</tbody></table></div>';
    listContainer.innerHTML = html;

    // Bind view buttons
    listContainer.querySelectorAll('.session-view-btn, .session-view-link').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.preventDefault();
        viewSession(btn.dataset.id);
      });
    });

    // Bind delete buttons
    listContainer.querySelectorAll('.session-delete-btn').forEach(btn => {
      btn.addEventListener('click', () => {
        deleteSession(btn.dataset.id);
      });
    });
  } catch (err) {
    listContainer.innerHTML = `<div class="text-center py-12 px-6 text-zinc-500 text-sm">Failed to load sessions: ${err.message}</div>`;
  }
}

async function viewSession(sessionId) {
  const detailContainer = _el.querySelector('#session-detail');
  if (!detailContainer) {return;}

  detailContainer.innerHTML = '<div class="text-center py-12 px-6 text-zinc-500 text-sm"><span class="spinner"></span> Loading...</div>';

  try {
    const result = await _client.call('sessions.history', { sessionId });
    const messages = result.messages ?? [];

    const roleClasses = {
      user: 'rounded-lg px-3 py-2 text-sm bg-blue-500/15 border border-blue-500/25 text-zinc-50',
      assistant: 'rounded-lg px-3 py-2 text-sm bg-zinc-900 border border-zinc-800 text-zinc-50',
      system: 'rounded-lg px-3 py-2 text-sm bg-zinc-800 text-zinc-400 border border-zinc-700',
    };

    let html = `
      <div class="mt-6">
        <div class="flex items-center justify-between mb-4">
          <h2 class="text-lg font-semibold text-zinc-50">${escapeHtml(sessionId)}</h2>
          <span class="text-sm text-zinc-500">${messages.length} messages</span>
        </div>
        <div class="flex flex-col gap-3 max-h-[60vh] overflow-y-auto p-3 bg-zinc-900 border border-zinc-800 rounded-lg">
    `;

    if (messages.length === 0) {
      html += '<div class="text-center py-12 px-6 text-zinc-500 text-sm">No messages in this session</div>';
    } else {
      for (const msg of messages) {
        const role = msg.role ?? 'system';
        const content = msg.content ?? msg.text ?? '';
        const cls = roleClasses[role] ?? roleClasses.system;
        html += `<div class="${cls}">${escapeHtml(content)}</div>`;
      }
    }

    html += '</div></div>';
    detailContainer.innerHTML = html;
  } catch (err) {
    detailContainer.innerHTML = `<div class="text-center py-12 px-6 text-zinc-500 text-sm">Failed to load session: ${err.message}</div>`;
  }
}

async function deleteSession(sessionId) {
  if (!confirm(`Delete session "${sessionId}"? This will clear all message history.`)) {
    return;
  }

  try {
    await _client.call('sessions.delete', { sessionId });
    await loadSessionList();
  } catch (err) {
    alert(`Failed to delete session: ${err.message}`);
  }
}

export const SessionsPage = {
  async render(el, client) {
    _client = client;
    _el = el;

    el.innerHTML = `
      <h1 class="text-2xl font-semibold text-zinc-50 mb-6">Sessions</h1>
      <div class="flex items-center gap-3 mb-4 flex-wrap">
        <label class="text-sm text-zinc-400 flex items-center gap-1.5" title="Filter sessions by source channel or UI frontend.">Frontend
          <select id="sessions-frontend-filter" class="bg-zinc-900 text-zinc-50 border border-zinc-800 rounded-lg px-3 py-1.5 text-sm outline-none focus:border-blue-500" title="Show only sessions from a specific frontend.">
            <option value="">All</option>
            <option value="ws">ws</option>
            <option value="tui">tui</option>
            <option value="telegram">telegram</option>
            <option value="slack">slack</option>
            <option value="discord">discord</option>
            <option value="mattermost">mattermost</option>
          </select>
        </label>
        <label class="text-sm text-zinc-400 flex items-center gap-2 cursor-pointer" title="Include persisted sessions that are no longer active.">
          <input id="sessions-include-inactive" type="checkbox" checked title="Toggle whether inactive/persisted sessions are listed." />
          Include inactive/persisted
        </label>
        <button id="sessions-refresh-btn" class="px-3 py-1.5 text-sm font-medium rounded-md border border-zinc-700 bg-zinc-800 text-zinc-200 hover:bg-zinc-700 transition-colors" title="Reload the session list from the gateway.">Refresh</button>
      </div>
      <div id="sessions-list"></div>
      <div id="session-detail"></div>
    `;

    const frontendSelect = el.querySelector('#sessions-frontend-filter');
    if (frontendSelect) {
      frontendSelect.value = _frontendFilter;
      frontendSelect.addEventListener('change', async () => {
        _frontendFilter = frontendSelect.value;
        await loadSessionList();
      });
    }

    const inactiveToggle = el.querySelector('#sessions-include-inactive');
    if (inactiveToggle) {
      inactiveToggle.checked = _includeInactive;
      inactiveToggle.addEventListener('change', async () => {
        _includeInactive = inactiveToggle.checked;
        await loadSessionList();
      });
    }

    const refreshBtn = el.querySelector('#sessions-refresh-btn');
    if (refreshBtn) {
      refreshBtn.addEventListener('click', async () => {
        await loadSessionList();
      });
    }

    await loadSessionList();
  },

  teardown() {
    _client = null;
    _el = null;
  },
};
