/**
 * Lego 09 / Lego 11 — Surveillance HUD Service
 *
 * Opens a persistent Socket.io connection to NestJS /monitor namespace.
 * Emits monitor:subscribe on connect and keeps the tunnel alive indefinitely.
 * Exposes signals for the PerformanceHUD and chatbot status indicators.
 *
 * Exposes nestStatus (ONLINE/OFFLINE) derived from socket connection state.
 */

import { Injectable, signal, computed, OnDestroy } from '@angular/core';
import { io, Socket } from 'socket.io-client';
import { environment } from '../../environments/environment';

export interface MonitorPayload {
  service: string;
  pid: number;
  cpu: number;
  memory: number;   // bytes
  timestamp: string;
}


@Injectable({ providedIn: 'root' })
export class SurveillanceService implements OnDestroy {

  /** Live metrics — HUD reads this signal directly */
  readonly metrics = signal<MonitorPayload[]>([]);
  readonly connected = signal<boolean>(false);

  /** Derived status string — consumed by Scanner and HUD */
  readonly nestStatus = computed<'ONLINE' | 'OFFLINE'>(() =>
    this.connected() ? 'ONLINE' : 'OFFLINE'
  );

  private socket: Socket;

  constructor() {
    // Persistent tunnel — opened on service construction (app boot)
    this.socket = io(`${environment.nestWsUrl}/monitor`, {
      transports: ['websocket'],
      reconnection: true,
      reconnectionDelay: 1000,
    });

    this.socket.on('connect', () => {
      this.connected.set(true);
      this.socket.emit('monitor:subscribe');
    });

    this.socket.on('disconnect', () => {
      this.connected.set(false);
    });

    this.socket.on('monitor:data', (payload: MonitorPayload[]) => {
      this.metrics.set(payload);
    });
  }

  ngOnDestroy() {
    this.socket.disconnect();
  }

  formatBytes(bytes: number): string {
    if (bytes === 0) return '0 B';
    const mb = bytes / (1024 * 1024);
    return `${mb.toFixed(1)} MB`;
  }
}
