import { BadRequestException, Body, Controller, Delete, Get, Headers, Post } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { ActorResolver, type MessagePrincipal } from '../identity/actor.resolver';
import { SessionVerifier } from '../platform/session.verifier';
import { SubscribeDto, UnsubscribeDto } from './notification.dto';

@Controller('v1/notifications')
export class NotificationController {
  constructor(
    private readonly prisma: PrismaService,
    private readonly actors: ActorResolver,
    private readonly session: SessionVerifier,
  ) {}

  /** The public VAPID key the client needs to create a push subscription. */
  @Get('vapid-public-key')
  vapidKey(): { key: string } {
    return { key: process.env.VAPID_PUBLIC_KEY ?? '' };
  }

  /** Store (or refresh) a push subscription for the caller. */
  @Post('subscribe')
  async subscribe(@Body() body: SubscribeDto, @Headers('authorization') auth?: string): Promise<{ ok: true }> {
    const principal = this.principal(auth);
    const scope = await this.actors.resolveScope(principal);
    const actor = await this.actors.resolveActor(scope.id, principal);
    await this.prisma.iiosNotificationSubscription.upsert({
      where: { endpoint: body.endpoint },
      create: { scopeId: scope.id, actorId: actor.id, kind: body.kind ?? 'webpush', endpoint: body.endpoint, p256dh: body.keys.p256dh, auth: body.keys.auth, userAgent: body.userAgent },
      update: { actorId: actor.id, p256dh: body.keys.p256dh, auth: body.keys.auth, lastSeenAt: new Date() },
    });
    return { ok: true };
  }

  @Delete('subscribe')
  async unsubscribe(@Body() body: UnsubscribeDto): Promise<{ ok: true }> {
    await this.prisma.iiosNotificationSubscription.deleteMany({ where: { endpoint: body.endpoint } });
    return { ok: true };
  }

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