import {
  Body,
  Controller,
  Headers,
  Post,
  Query,
  Res,
} from '@nestjs/common';
import type { Response } from 'express';
import { Public } from '@common/decorators/public.decorator';
import { SkipTransform } from '@common/decorators/skip-transform.decorator';
import { createLogger } from '@core/observability/logging/config/winston.config';
import { OutlookSyncService } from '../services/outlook-sync.service';

const logger = createLogger('MeetingAttendanceOutlookWebhookController');

@Controller('meeting-attendance/integrations/outlook/webhooks')
@SkipTransform()
export class MeetingAttendanceOutlookWebhookController {
  constructor(private readonly outlookSyncService: OutlookSyncService) {}

  @Post('notifications')
  @Public()
  async handleNotification(
    @Query('validationToken') validationToken: string | undefined,
    @Body() body: any,
    @Headers('client-state') headerClientState: string | undefined,
    @Res() res: Response,
  ) {
    if (validationToken) {
      res.setHeader('Content-Type', 'text/plain');
      return res.status(200).send(decodeURIComponent(validationToken));
    }

    const notifications = Array.isArray(body?.value) ? body.value : [];
    await this.outlookSyncService.handleChangeNotifications(
      notifications.map((item: any) => ({
        ...item,
        clientState: item?.clientState || headerClientState,
      })),
    );

    return res.status(202).json({ accepted: true, received: notifications.length });
  }

  @Post('lifecycle')
  @Public()
  async handleLifecycle(
    @Query('validationToken') validationToken: string | undefined,
    @Body() body: any,
    @Res() res: Response,
  ) {
    if (validationToken) {
      res.setHeader('Content-Type', 'text/plain');
      return res.status(200).send(decodeURIComponent(validationToken));
    }

    const lifecycleEvents = Array.isArray(body?.value) ? body.value : [];
    await this.outlookSyncService.handleLifecycleNotifications(lifecycleEvents);
    for (const item of lifecycleEvents) {
      logger.warn(
        `Received Outlook lifecycle notification, event=${item?.lifecycleEvent}, subscriptionId=${item?.subscriptionId}`,
      );
    }

    return res.status(202).json({ accepted: true, received: lifecycleEvents.length });
  }
}
