import * as plugins from '../../plugins.ts';
import type { OpsServer } from '../classes.opsserver.ts';
import * as interfaces from '../../../ts_interfaces/index.ts';
import { requireValidIdentity } from '../helpers/guards.ts';

export class ConnectionsHandler {
  public typedrouter = new plugins.typedrequest.TypedRouter();

  constructor(private opsServerRef: OpsServer) {
    this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
    this.registerHandlers();
  }

  private get actionLog() {
    return this.opsServerRef.gitopsAppRef.actionLog;
  }

  private registerHandlers(): void {
    // Get all connections
    this.typedrouter.addTypedHandler(
      new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetConnections>(
        'getConnections',
        async (dataArg) => {
          await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
          const connections = this.opsServerRef.gitopsAppRef.connectionManager.getConnections();
          return { connections };
        },
      ),
    );

    // Create connection
    this.typedrouter.addTypedHandler(
      new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateConnection>(
        'createConnection',
        async (dataArg) => {
          await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
          const connection = await this.opsServerRef.gitopsAppRef.connectionManager.createConnection(
            dataArg.name,
            dataArg.providerType,
            dataArg.baseUrl,
            dataArg.token,
            dataArg.groupFilter,
          );
          this.actionLog.append({
            actionType: 'create',
            entityType: 'connection',
            entityId: connection.id,
            entityName: connection.name,
            details: `Created ${dataArg.providerType} connection "${dataArg.name}" (${dataArg.baseUrl})`,
            username: dataArg.identity.username,
          });
          return { connection };
        },
      ),
    );

    // Update connection
    this.typedrouter.addTypedHandler(
      new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateConnection>(
        'updateConnection',
        async (dataArg) => {
          await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
          const connection = await this.opsServerRef.gitopsAppRef.connectionManager.updateConnection(
            dataArg.connectionId,
            {
              name: dataArg.name,
              baseUrl: dataArg.baseUrl,
              token: dataArg.token,
              groupFilter: dataArg.groupFilter,
            },
          );
          const fields = [
            dataArg.name && 'name',
            dataArg.baseUrl && 'baseUrl',
            dataArg.token && 'token',
            dataArg.groupFilter !== undefined && 'groupFilter',
          ].filter(Boolean).join(', ');
          this.actionLog.append({
            actionType: 'update',
            entityType: 'connection',
            entityId: dataArg.connectionId,
            entityName: connection.name,
            details: `Updated connection "${connection.name}" (fields: ${fields})`,
            username: dataArg.identity.username,
          });
          return { connection };
        },
      ),
    );

    // Pause/resume connection
    this.typedrouter.addTypedHandler(
      new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_PauseConnection>(
        'pauseConnection',
        async (dataArg) => {
          await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
          const connection = await this.opsServerRef.gitopsAppRef.connectionManager.pauseConnection(
            dataArg.connectionId,
            dataArg.paused,
          );
          this.actionLog.append({
            actionType: dataArg.paused ? 'pause' : 'resume',
            entityType: 'connection',
            entityId: dataArg.connectionId,
            entityName: connection.name,
            details: `${dataArg.paused ? 'Paused' : 'Resumed'} connection "${connection.name}"`,
            username: dataArg.identity.username,
          });
          return { connection };
        },
      ),
    );

    // Test connection
    this.typedrouter.addTypedHandler(
      new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_TestConnection>(
        'testConnection',
        async (dataArg) => {
          await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
          const result = await this.opsServerRef.gitopsAppRef.connectionManager.testConnection(
            dataArg.connectionId,
          );
          const conn = this.opsServerRef.gitopsAppRef.connectionManager.getConnections()
            .find((c) => c.id === dataArg.connectionId);
          this.actionLog.append({
            actionType: 'test',
            entityType: 'connection',
            entityId: dataArg.connectionId,
            entityName: conn?.name || dataArg.connectionId,
            details: `Tested connection: ${result.ok ? 'success' : `failed — ${result.error || 'unknown error'}`}`,
            username: dataArg.identity.username,
          });
          return result;
        },
      ),
    );

    // Delete connection
    this.typedrouter.addTypedHandler(
      new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteConnection>(
        'deleteConnection',
        async (dataArg) => {
          await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
          const conn = this.opsServerRef.gitopsAppRef.connectionManager.getConnections()
            .find((c) => c.id === dataArg.connectionId);
          await this.opsServerRef.gitopsAppRef.connectionManager.deleteConnection(
            dataArg.connectionId,
          );
          this.actionLog.append({
            actionType: 'delete',
            entityType: 'connection',
            entityId: dataArg.connectionId,
            entityName: conn?.name || dataArg.connectionId,
            details: `Deleted connection "${conn?.name || dataArg.connectionId}"`,
            username: dataArg.identity.username,
          });
          return { ok: true };
        },
      ),
    );
  }
}
