import {
  Body,
  Controller,
  ForbiddenException,
  Get,
  HttpCode,
  HttpStatus,
  Post,
  UseGuards,
} from '@nestjs/common';
import { Throttle } from '@nestjs/throttler';
import {
  MissionStateResponse,
  MissionStateResponseSchema,
  StartMissionRequestSchema,
} from '@fog-explorer/api-interfaces';
import {
  TwitchClaims,
  TwitchJwtGuard,
  TwitchJwtPayload,
} from '../auth/twitch-jwt.guard';
import { MissionStoreService } from './mission-store.service';
import { MissionsService } from './missions.service';

@Controller('missions')
@UseGuards(TwitchJwtGuard)
export class MissionsController {
  constructor(
    private readonly store: MissionStoreService,
    private readonly missions: MissionsService,
  ) {}

  @Get('state')
  @Throttle({ default: { limit: 100, ttl: 1000 } })
  async getState(
    @TwitchClaims() claims: TwitchJwtPayload,
  ): Promise<MissionStateResponse> {
    const state = await this.store.getStateForChannel(claims.channel_id);
    return MissionStateResponseSchema.parse(state);
  }

  @Post('abandon')
  @HttpCode(HttpStatus.NO_CONTENT)
  async abandonMission(
    @TwitchClaims() claims: TwitchJwtPayload,
  ): Promise<void> {
    if (!claims.opaque_user_id.startsWith('U')) {
      throw new ForbiddenException('Anonymous viewers cannot abandon missions');
    }
    await this.missions.abandonMission(claims);
  }

  @Post('start')
  @HttpCode(HttpStatus.CREATED)
  async startMission(
    @TwitchClaims() claims: TwitchJwtPayload,
    @Body() body: unknown,
  ): Promise<NonNullable<MissionStateResponse>> {
    if (!claims.opaque_user_id.startsWith('U')) {
      throw new ForbiddenException('Anonymous viewers cannot start missions');
    }
    const { difficulty, durationMinutes, characterName } = StartMissionRequestSchema.parse(body);
    return this.missions.startMission(claims, difficulty, durationMinutes, characterName);
  }
}
