/**
 * 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.
 *
 * n8nStatus is driven by monitor:status events emitted by NestJS every time
 * its server-side webhook probe result changes (probed every 10 s). This is
 * truth-based: NestJS POSTs to the actual webhook, not just a port check.
 */

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;
}

export interface MonitorStatus {
  n8nWebhookReady: boolean;
  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'
  );

  /**
   * n8n agent readiness — driven by NestJS webhook probe via monitor:status.
   * 'checking' until the first probe result arrives after connect.
   */
  readonly n8nStatus = signal<'checking' | 'ready' | 'not-ready'>('checking');

  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.n8nStatus.set('checking');
      // Lego 11: emit monitor:subscribe to start the data stream
      this.socket.emit('monitor:subscribe');
    });

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

    // Every 500ms tick from NestJS SurveillanceService
    this.socket.on('monitor:data', (payload: MonitorPayload[]) => {
      this.metrics.set(payload);
    });

    // Webhook probe result — emitted immediately on connect and on every change
    this.socket.on('monitor:status', (status: MonitorStatus) => {
      this.n8nStatus.set(status.n8nWebhookReady ? 'ready' : 'not-ready');
    });
  }

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

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