import {
  Body,
  Controller,
  ForbiddenException,
  Get,
  Headers,
  Inject,
  Param,
  Post,
  UseGuards,
} from '@nestjs/common';
import { AuthGuard } from '../auth/auth.guard.js';
import { CurrentUser } from '../auth/current-user.decorator.js';
import { scopeFromUser, type AuthenticatedUserLike } from '../auth/session-scope.js';
import type { RuntimeProviderRequestContext } from '../agent/runtime-provider-registry.service.js';
import type {
  InteractionCoordinationObservationDto,
  InteractionCoordinationResponseDto,
  InteractionCoordinationResultDto,
  CreateHandoffDto,
} from './interaction-coordination.dto.js';
import { InteractionCoordinationService } from './interaction-coordination.service.js';

/** Authenticated interaction-plane boundary for the handoff/observe/result-only interaction coordination contract. */
/** `api/coord/interaction` is canonical; the Mos path remains a compatibility alias. */
@Controller(['api/coord/interaction', 'api/coord/mos'])
@UseGuards(AuthGuard)
export class InteractionCoordinationController {
  constructor(
    @Inject(InteractionCoordinationService)
    private readonly coordination: InteractionCoordinationService,
  ) {}

  @Post('handoff')
  async handoff(
    @Body() request: CreateHandoffDto,
    @CurrentUser() user: AuthenticatedUserLike,
    @Headers('x-correlation-id') correlationId?: string,
  ): Promise<InteractionCoordinationResponseDto> {
    return { receipt: await this.coordination.handoff(request, this.context(user, correlationId)) };
  }

  @Get(':handoffId/observe')
  async observe(
    @Param('handoffId') handoffId: string,
    @CurrentUser() user: AuthenticatedUserLike,
    @Headers('x-correlation-id') correlationId?: string,
  ): Promise<InteractionCoordinationObservationDto> {
    return {
      observation: await this.coordination.observe(handoffId, this.context(user, correlationId)),
    };
  }

  @Get(':handoffId/result')
  async result(
    @Param('handoffId') handoffId: string,
    @CurrentUser() user: AuthenticatedUserLike,
    @Headers('x-correlation-id') correlationId?: string,
  ): Promise<InteractionCoordinationResultDto> {
    return { result: await this.coordination.result(handoffId, this.context(user, correlationId)) };
  }

  private context(
    user: AuthenticatedUserLike,
    correlationId?: string,
  ): RuntimeProviderRequestContext {
    const requestCorrelationId = correlationId?.trim();
    if (!requestCorrelationId) throw new ForbiddenException('X-Correlation-Id is required');
    return {
      actorScope: scopeFromUser(user),
      channelId: 'cli',
      correlationId: requestCorrelationId,
    };
  }
}
