import * as plugins from '../../plugins.js';
import type { OpsServer } from '../classes.opsserver.js';
import * as interfaces from '../../../ts_interfaces/index.js';
import { requireOpsAuth } from '../helpers/auth.js';

/**
 * Handler for OpsServer user accounts. Registers on adminRouter,
 * so admin middleware enforces auth + role check before the handler runs.
 * User data is owned by AdminHandler; this handler just exposes a safe
 * projection of it via TypedRequest.
 */
export class UsersHandler {
  constructor(private opsServerRef: OpsServer) {
    this.registerHandlers();
  }

  private registerHandlers(): void {
    const router = this.opsServerRef.adminRouter;

    // List users (admin-only)
    router.addTypedHandler(
      new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ListUsers>(
        'listUsers',
        async (dataArg) => {
          await requireOpsAuth(this.opsServerRef, dataArg, {
            scope: 'users:read',
            requireAdminIdentity: true,
            requireAdminToken: true,
          });
          const users = await this.opsServerRef.adminHandler.listUsers();
          return { users };
        },
      ),
    );

    router.addTypedHandler(
      new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateUser>(
        'createUser',
        async (dataArg) => {
          await requireOpsAuth(this.opsServerRef, dataArg, {
            scope: 'users:manage',
            requireAdminIdentity: true,
            requireAdminToken: true,
          });
          return this.opsServerRef.adminHandler.createUser({
            email: dataArg.email,
            name: dataArg.name,
            role: dataArg.role,
            password: dataArg.password,
            enableIdpGlobalAuth: dataArg.enableIdpGlobalAuth,
          });
        },
      ),
    );

    router.addTypedHandler(
      new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteUser>(
        'deleteUser',
        async (dataArg) => {
          const auth = await requireOpsAuth(this.opsServerRef, dataArg, {
            scope: 'users:manage',
            requireAdminIdentity: true,
            requireAdminToken: true,
          });
          return this.opsServerRef.adminHandler.deleteUser({
            id: dataArg.id,
            requestingUserId: auth.userId,
          });
        },
      ),
    );
  }
}
