import { BadRequestException, Body, Controller, Get, Headers, HttpCode, Param, Post, Req } from '@nestjs/common';
import type { Request } from 'express';
import { InboundService } from './inbound.service';
import { OutboundService } from './outbound.service';
import { SessionVerifier } from '../platform/session.verifier';
import { PrismaService } from '../prisma/prisma.service';
import { SendDto } from './adapters.dto';

@Controller('v1/adapters')
export class AdaptersController {
  constructor(
    private readonly inbound: InboundService,
    private readonly outbound: OutboundService,
    private readonly session: SessionVerifier,
    private readonly prisma: PrismaService,
  ) {}

  /** Provider webhook. Authenticated by HMAC signature (not a session token). */
  @Post(':channelType/webhook')
  @HttpCode(202)
  async webhook(@Param('channelType') channelType: string, @Req() req: Request & { rawBody?: Buffer }) {
    const rawBody = req.rawBody ? req.rawBody.toString('utf8') : JSON.stringify(req.body ?? {});
    const headers = req.headers as Record<string, string | undefined>;
    return this.inbound.receive(channelType, rawBody, headers);
  }

  /** Outbound to the sandbox sink (session-auth). No real network. */
  @Post(':channelType/send')
  async send(@Param('channelType') channelType: string, @Body() body: SendDto, @Headers('authorization') auth?: string) {
    this.requireSession(auth);
    return this.outbound.send(channelType, body.target, body.payload ?? {}, body.idempotencyKey);
  }

  // ─── inspector reads (session-auth) ───────────────────────────────
  @Get('inbound')
  async listInbound(@Headers('authorization') auth?: string) {
    this.requireSession(auth);
    return this.prisma.iiosInboundRawEvent.findMany({ orderBy: { createdAt: 'desc' }, take: 50 });
  }

  @Get('outbound')
  async listOutbound(@Headers('authorization') auth?: string) {
    this.requireSession(auth);
    return this.prisma.iiosOutboundCommand.findMany({ orderBy: { createdAt: 'desc' }, take: 50, include: { attempts: true } });
  }

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