import { LitElement, html, nothing } from '/vendor/lit/lit.min.js';
import { repeat } from '/vendor/lit/lit.min.js';
import { unsafeHTML } from '/vendor/lit/lit.min.js';
import { sortByPriority, escapeHtml } from './utils.js';
import './session-tile.js';

/**
 * <session-grid> - Dashboard grid of session tiles.
 *
 * Owns sorting, grouping, status tiles, and the keyed repeat loop.
 * Replaces the renderGrid() function's innerHTML + diff-patch approach.
 *
 * Properties:
 *   sessions:          Array   - raw session list (includes status sentinels)
 *   visibleSessions:   Array   - already-filtered visible sessions
 *   sortOrder:         String  - 'alphabetical' | 'recent' | 'manual'
 *   groupMode:         String  - 'flat' | 'grouped'
 *   mobile:            Boolean - mobile layout
 *   multiDevice:       Boolean - multi-device enabled
 *   showDeviceBadges:  Boolean
 *   activityIndicator: String
 *   viewMode:          String  - 'auto' | 'fit'
 *
 * Events:
 *   session-open    { name, remoteId }
 *   session-options { name, remoteId, sessionKey, rect }
 */
export class SessionGrid extends LitElement {
  static properties = {
    sessions:          { type: Array },
    visibleSessions:   { type: Array },
    sortOrder:         { type: String, attribute: 'sort-order' },
    groupMode:         { type: String, attribute: 'group-mode' },
    mobile:            { type: Boolean },
    multiDevice:       { type: Boolean, attribute: 'multi-device' },
    showDeviceBadges:  { type: Boolean, attribute: 'show-device-badges' },
    activityIndicator: { type: String, attribute: 'activity-indicator' },
    viewMode:          { type: String, attribute: 'view-mode' },
  };

  // Light DOM so existing CSS grid styles apply
  createRenderRoot() { return this; }

  constructor() {
    super();
    this.sessions = [];
    this.visibleSessions = [];
    this.sortOrder = 'manual';
    this.groupMode = 'flat';
    this.mobile = false;
    this.multiDevice = false;
    this.showDeviceBadges = true;
    this.activityIndicator = 'both';
    this.viewMode = 'auto';
  }

  get _ordered() {
    const visible = this.visibleSessions || [];
    if (this.sortOrder === 'alphabetical') {
      return visible.slice().sort((a, b) => (a.name || '').localeCompare(b.name || ''));
    }
    return this.mobile ? sortByPriority(visible) : visible;
  }

  get _statusTiles() {
    return (this.sessions || []).filter(s =>
      s.status === 'auth_failed' || s.status === 'unreachable'
    );
  }

  _onTileClick(e) {
    this.dispatchEvent(new CustomEvent('session-open', {
      bubbles: true, composed: true,
      detail: e.detail,
    }));
  }

  _onTileOptions(e) {
    this.dispatchEvent(new CustomEvent('session-options', {
      bubbles: true, composed: true,
      detail: e.detail,
    }));
  }

  _renderTile(s) {
    return html`
      <session-tile
        .session=${s}
        ?mobile=${this.mobile}
        ?multi-device=${this.multiDevice}
        ?show-device-badges=${this.showDeviceBadges}
        activity-indicator=${this.activityIndicator}
        view-mode=${this.viewMode}
        @tile-click=${this._onTileClick}
        @tile-options=${this._onTileOptions}
      ></session-tile>
    `;
  }

  _renderStatusTile(s) {
    const label = s.status === 'auth_failed' ? 'Auth required' : 'Offline';
    const cls = s.status === 'auth_failed' ? 'auth' : 'offline';
    const name = escapeHtml(s.deviceName || 'Unknown');
    return html`
      <article class="session-tile source-tile--${cls}">
        <div class="tile-header">
          <span class="tile-name">${name}</span>
          <span class="tile-meta source-tile__status">${label}</span>
        </div>
      </article>
    `;
  }

  render() {
    const ordered = this._ordered;
    const statusTiles = this._statusTiles;

    if (ordered.length === 0 && statusTiles.length === 0) {
      return nothing;
    }

    if (this.groupMode === 'grouped') {
      const groups = new Map();
      const groupOrder = [];
      for (const s of ordered) {
        const dn = s.deviceName || 'Unknown';
        if (!groups.has(dn)) { groups.set(dn, []); groupOrder.push(dn); }
        groups.get(dn).push(s);
      }

      return html`
        ${groupOrder.map(gname => html`
          <h3 class="device-group-header">${gname}</h3>
          ${repeat(groups.get(gname), s => s.sessionKey || s.name, s => this._renderTile(s))}
        `)}
        ${statusTiles.map(s => this._renderStatusTile(s))}
      `;
    }

    return html`
      ${repeat(ordered, s => s.sessionKey || s.name, s => this._renderTile(s))}
      ${statusTiles.map(s => this._renderStatusTile(s))}
    `;
  }
}

customElements.define('session-grid', SessionGrid);