import { BadRequestException, Body, Controller, Get, Headers, Param, Post, Query } from '@nestjs/common';
import { IiosOutputFormat, IiosRouteMode } from '@prisma/client';
import { RouteService } from './route.service';
import { SessionVerifier } from '../platform/session.verifier';
import type { MessagePrincipal } from '../identity/actor.resolver';
import { CreateBindingDto, SimulateDto } from './route.dto';

@Controller('v1/routes')
export class RouteController {
  constructor(
    private readonly routes: RouteService,
    private readonly session: SessionVerifier,
  ) {}

  @Post('bindings')
  async createBinding(@Body() body: CreateBindingDto, @Headers('authorization') auth?: string) {
    return this.routes.createBinding(this.principal(auth), {
      ...body,
      mode: body.mode as IiosRouteMode | undefined,
      outputFormat: body.outputFormat as IiosOutputFormat | undefined,
    });
  }

  @Get('bindings')
  async listBindings(@Headers('authorization') auth?: string) {
    return this.routes.listBindings(this.principal(auth));
  }

  @Post('simulate')
  async simulate(@Body() body: SimulateDto, @Headers('authorization') auth?: string) {
    this.principal(auth);
    return this.routes.simulate(body.interactionId, { channelType: body.originChannelType, ref: body.originRef });
  }

  @Get('decisions')
  async decisions(@Query('state') state?: string, @Headers('authorization') auth?: string) {
    return this.routes.listDecisions(this.principal(auth), { state });
  }

  @Post('decisions/:id/approve')
  async approve(@Param('id') id: string, @Headers('authorization') auth?: string) {
    return this.routes.approve(id, this.principal(auth));
  }

  @Post('decisions/:id/deny')
  async deny(@Param('id') id: string, @Headers('authorization') auth?: string) {
    return this.routes.deny(id, this.principal(auth));
  }

  @Post('bindings/:id/flush-digest')
  async flushDigest(@Param('id') id: string, @Headers('authorization') auth?: string) {
    this.principal(auth);
    return this.routes.flushDigest(id);
  }

  private principal(authorization?: string): MessagePrincipal {
    const token = (authorization ?? '').replace(/^Bearer\s+/i, '');
    if (!token) throw new BadRequestException('Authorization bearer token is required');
    return this.session.verify(token);
  }
}
