import { Body, Controller, Get, HttpException, HttpStatus, Put, 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 { HarnessOperationError } from './harness.registry.js';
import { HarnessSelectionService } from './harness-selection.service.js';
import { HarnessSelectionInputDto, type SelectionResponseDto } from './harness.dto.js';

/**
 * Chat-preferences selection surface. The scope is ALWAYS derived on the server
 * from the authenticated user (`scopeFromUser(CurrentUser)`); the request body and
 * query string can never name another user, tenant, or seat. A typed selection
 * failure (unknown tuple → `selection_invalid`, known-but-unavailable →
 * `model_unavailable`) is returned as 422 with the requested tuple echoed back
 * unchanged, and never mutates the stored selection.
 */
@Controller('api/chat/preferences/selection')
@UseGuards(AuthGuard)
export class HarnessSelectionController {
  constructor(private readonly selection: HarnessSelectionService) {}

  @Get()
  get(@CurrentUser() user: AuthenticatedUserLike): SelectionResponseDto {
    return { selection: this.selection.getSelection(scopeFromUser(user)) };
  }

  @Put()
  async put(
    @CurrentUser() user: AuthenticatedUserLike,
    @Body() dto: HarnessSelectionInputDto,
  ): Promise<SelectionResponseDto> {
    try {
      const stored = await this.selection.setSelection(scopeFromUser(user), {
        harnessId: dto.harnessId,
        providerId: dto.providerId,
        modelId: dto.modelId,
      });
      return { selection: stored };
    } catch (error) {
      if (error instanceof HarnessOperationError) {
        throw new HttpException(error.dto, HttpStatus.UNPROCESSABLE_ENTITY);
      }
      throw error;
    }
  }
}
