/// Device management view — list devices with revoke actions.

import { setState, sendMessage, navigate, escapeHtml } from '../../shared/state';
import type { Device } from '../../shared/types';

interface RevokedEntry {
  name: string;
  public_key: string;
  revoked_at: number;
  revoked_by: string;
}

function relativeTime(unixSec: number): string {
  const now = Math.floor(Date.now() / 1000);
  const diff = now - unixSec;
  if (diff < 60)    return 'just now';
  if (diff < 3600)  return `${Math.floor(diff / 60)}m ago`;
  if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;
  if (diff < 2592000) return `${Math.floor(diff / 86400)}d ago`;
  return `${Math.floor(diff / 2592000)}mo ago`;
}

function detectDefaultDeviceName(): string {
  const ua = navigator.userAgent ?? '';
  const platform = (navigator.platform ?? '').toLowerCase();
  const isFirefox = /firefox/i.test(ua);
  const isEdge = /edg/i.test(ua);
  const isChrome = /chrome/i.test(ua) && !isEdge;
  const browser = isFirefox ? 'Firefox' : isEdge ? 'Edge' : isChrome ? 'Chrome' : 'Browser';
  const os = platform.includes('mac') ? 'macOS'
    : platform.includes('win') ? 'Windows'
    : platform.includes('linux') ? 'Linux'
    : 'Unknown';
  return `${browser} on ${os}`;
}

export function teardown(): void {
  // No cleanup needed
}

export async function renderDevices(app: HTMLElement): Promise<void> {
  // Get current device name from local storage
  const stored = await chrome.storage.local.get(['device_name']);
  const currentDeviceName: string | undefined = stored.device_name as string | undefined;

  // Fetch active device list and revoked list in parallel
  const [devicesResp, revokedResp] = await Promise.all([
    sendMessage({ type: 'list_devices' }),
    sendMessage({ type: 'list_revoked' }),
  ]);

  if (!devicesResp.ok) {
    app.innerHTML = `<div class="pad"><p class="error">Failed to load devices</p></div>`;
    return;
  }

  const devices = (devicesResp.data as { devices: Device[] }).devices;
  const revokedDevices: RevokedEntry[] = revokedResp.ok
    ? (revokedResp.data as { revoked: RevokedEntry[] }).revoked
    : [];

  const isRegistered = currentDeviceName && devices.some((d) => d.name === currentDeviceName);

  const activeDevicesHtml = devices.length === 0
    ? `<p class="muted" style="text-align:center;margin-top:32px;">No devices registered</p>`
    : devices.map((d) => {
        const isCurrentDevice = d.name === currentDeviceName;
        return `
          <div class="device-row">
            <div class="device-row__info">
              <span class="device-row__name">${escapeHtml(d.name)}${isCurrentDevice ? ' <span class="device-row__you">← you</span>' : ''}</span>
              <span class="device-row__meta">added ${relativeTime(d.added_at)}</span>
            </div>
            ${isCurrentDevice ? '' : `<button class="device-row__revoke" data-revoke="${escapeHtml(d.name)}">revoke</button>`}
          </div>
        `;
      }).join('');

  const revokedSectionHtml = revokedDevices.length === 0 ? '' : `
    <details class="revoked-section" style="margin-top:16px;">
      <summary class="muted" style="cursor:pointer;font-size:0.85em;">
        ${revokedDevices.length} revoked device${revokedDevices.length !== 1 ? 's' : ''}
      </summary>
      <div style="margin-top:8px;">
        ${revokedDevices.map((r) => `
          <div class="device-row device-row--revoked">
            <div class="device-row__info">
              <span class="device-row__name" style="text-decoration:line-through;opacity:0.5;">
                ${escapeHtml(r.name)}
              </span>
              <span class="device-row__meta">
                revoked ${relativeTime(r.revoked_at)}
                ${r.revoked_by !== 'unknown' ? ` by ${escapeHtml(r.revoked_by)}` : ''}
              </span>
            </div>
          </div>
        `).join('')}
      </div>
    </details>
  `;

  app.innerHTML = `
    <div class="pad">
      <div class="devices-header">
        <button class="btn" id="back-btn">← back</button>
        <h3 style="margin:0;">devices</h3>
      </div>
      ${!isRegistered ? `
        <div class="device-banner">
          <span>⚠ This device is not registered</span>
          <button class="btn btn-primary" id="register-btn">Register this device</button>
        </div>
      ` : ''}
      ${activeDevicesHtml}
      ${revokedSectionHtml}
    </div>
  `;

  // Wire handlers
  document.getElementById('back-btn')?.addEventListener('click', () => navigate('list'));

  document.getElementById('register-btn')?.addEventListener('click', () => {
    const banner = document.querySelector('.device-banner');
    if (!banner) return;
    const defaultName = detectDefaultDeviceName();
    banner.innerHTML = `
      <label class="label" for="register-name-input" style="display:block;margin-bottom:4px;">
        Name this device
      </label>
      <input
        id="register-name-input"
        type="text"
        value="${escapeHtml(defaultName)}"
        style="width:100%;margin-bottom:8px;"
      >
      <div style="display:flex;gap:8px;">
        <button class="btn btn-primary" id="register-confirm-btn">Register</button>
        <button class="btn" id="register-cancel-btn">Cancel</button>
      </div>
    `;

    document.getElementById('register-cancel-btn')?.addEventListener('click', () => {
      renderDevices(app);
    });

    document.getElementById('register-confirm-btn')?.addEventListener('click', async () => {
      const input = document.getElementById('register-name-input') as HTMLInputElement | null;
      const name = input?.value.trim();
      if (!name) {
        setState({ error: 'Device name is required' });
        return;
      }
      const result = await sendMessage({ type: 'register_this_device', name });
      if (result.ok) {
        renderDevices(app);
      } else {
        setState({ error: result.error });
      }
    });
  });

  document.querySelectorAll<HTMLButtonElement>('[data-revoke]').forEach((btn) => {
    btn.addEventListener('click', async () => {
      const name = btn.dataset.revoke;
      if (!name) return;
      if (!confirm(`Revoke ${name}? This device will no longer be authorized.`)) return;

      btn.disabled = true;
      btn.textContent = '...';
      const result = await sendMessage({ type: 'revoke_device', name });
      if (result.ok) {
        await sendMessage({ type: 'sync' });
        renderDevices(app);
      } else {
        setState({ error: result.error });
      }
    });
  });
}
