import { BadRequestException, Body, Controller, Get, HttpCode, Param, Put } from '@nestjs/common';
import type { AuthenticatedUser } from '../../common/auth/authenticated-user';
import { CurrentUser } from '../../common/auth/current-user.decorator';
import { SetStateDto } from './dto/set-state.dto';
import { StateService } from './state.service';

/**
 * Keys are stable identifiers emitted by the frontend modules, so anything
 * outside the known shape is rejected rather than stored — a logged-in client
 * must not be able to fill the store with arbitrary rows.
 */
const STATE_KEY_PATTERN = /^[A-Za-z0-9_.:-]{1,200}$/;

function assertStateKey(key: string): string {
  if (!STATE_KEY_PATTERN.test(key)) {
    throw new BadRequestException('Invalid state key.');
  }
  return key;
}

/**
 * Per-user key/value store backing every terminal module. Rows belong to the
 * authenticated session user — there is no shared or anonymous bucket, so an
 * unauthenticated request never reaches the database.
 */
@Controller('state')
export class StateController {
  constructor(private readonly state: StateService) {}

  @Get(':key')
  async get(@CurrentUser() user: AuthenticatedUser, @Param('key') key: string) {
    const value = await this.state.get(user.id, assertStateKey(key));
    return { value };
  }

  @Put(':key')
  @HttpCode(204)
  async set(
    @CurrentUser() user: AuthenticatedUser,
    @Param('key') key: string,
    @Body() body: SetStateDto,
  ) {
    await this.state.set(user.id, assertStateKey(key), body.value);
  }
}
