import * as plugins from '../plugins.ts';
import { logger } from '../logging.ts';
import type { Onebox } from '../classes/onebox.ts';
import * as handlers from './handlers/index.ts';
import { files as bundledFiles } from '../../ts_bundled/bundle.ts';

export class OpsServer {
  public oneboxRef: Onebox;
  public typedrouter = new plugins.typedrequest.TypedRouter();
  public server!: plugins.typedserver.utilityservers.UtilityWebsiteServer;

  // Handler instances
  public adminHandler!: handlers.AdminHandler;
  public statusHandler!: handlers.StatusHandler;
  public servicesHandler!: handlers.ServicesHandler;
  public platformHandler!: handlers.PlatformHandler;
  public sslHandler!: handlers.SslHandler;
  public domainsHandler!: handlers.DomainsHandler;
  public dnsHandler!: handlers.DnsHandler;
  public registryHandler!: handlers.RegistryHandler;
  public networkHandler!: handlers.NetworkHandler;
  public backupsHandler!: handlers.BackupsHandler;
  public schedulesHandler!: handlers.SchedulesHandler;
  public settingsHandler!: handlers.SettingsHandler;
  public logsHandler!: handlers.LogsHandler;

  constructor(oneboxRef: Onebox) {
    this.oneboxRef = oneboxRef;
  }

  public async start(port = 3000) {
    this.server = new plugins.typedserver.utilityservers.UtilityWebsiteServer({
      domain: 'localhost',
      feedMetadata: undefined,
      bundledContent: bundledFiles,
    });

    // Chain typedrouters: server -> opsServer -> individual handlers
    this.server.typedrouter.addTypedRouter(this.typedrouter);

    // Set up all handlers
    await this.setupHandlers();

    await this.server.start(port);
    logger.success(`OpsServer started on http://localhost:${port}`);
  }

  private async setupHandlers(): Promise<void> {
    // AdminHandler requires async initialization for JWT key generation
    this.adminHandler = new handlers.AdminHandler(this);
    await this.adminHandler.initialize();

    // All other handlers self-register in their constructors
    this.statusHandler = new handlers.StatusHandler(this);
    this.servicesHandler = new handlers.ServicesHandler(this);
    this.platformHandler = new handlers.PlatformHandler(this);
    this.sslHandler = new handlers.SslHandler(this);
    this.domainsHandler = new handlers.DomainsHandler(this);
    this.dnsHandler = new handlers.DnsHandler(this);
    this.registryHandler = new handlers.RegistryHandler(this);
    this.networkHandler = new handlers.NetworkHandler(this);
    this.backupsHandler = new handlers.BackupsHandler(this);
    this.schedulesHandler = new handlers.SchedulesHandler(this);
    this.settingsHandler = new handlers.SettingsHandler(this);
    this.logsHandler = new handlers.LogsHandler(this);

    logger.success('OpsServer TypedRequest handlers initialized');
  }

  public async stop() {
    if (this.server) {
      await this.server.stop();
      logger.success('OpsServer stopped');
    }
  }
}
