import { BadRequestException, Body, Controller, Get, Headers, Param, Post, Query } from '@nestjs/common';
import { IiosConsentStatus, IiosMeetingType } from '@prisma/client';
import { CalendarService } from './calendar.service';
import { CalendarAdapter } from './calendar-adapter';
import { SessionVerifier } from '../platform/session.verifier';
import type { MessagePrincipal } from '../identity/actor.resolver';
import { ConsentDto, RequestMeetingDto, ScheduleMeetingDto } from './calendar.dto';

@Controller('v1/calendar')
export class CalendarController {
  constructor(
    private readonly calendar: CalendarService,
    private readonly adapter: CalendarAdapter,
    private readonly session: SessionVerifier,
  ) {}

  @Post('meetings')
  async schedule(@Body() body: ScheduleMeetingDto, @Headers('authorization') auth?: string) {
    return this.calendar.scheduleDirect(this.principal(auth), { ...body, meetingType: body.meetingType as IiosMeetingType });
  }

  @Post('requests')
  async request(
    @Body() body: RequestMeetingDto,
    @Query('fromCallback') fromCallback?: string,
    @Query('fromClaim') fromClaim?: string,
    @Headers('authorization') auth?: string,
  ) {
    const principal = this.principal(auth);
    if (fromCallback) return this.calendar.fromCallback(principal, fromCallback, body.requestedWindow);
    if (fromClaim) return this.calendar.fromEventClaim(principal, fromClaim, body.requestedWindow);
    return this.calendar.requestMeeting(principal, {
      requestedWindow: body.requestedWindow,
      meetingType: body.meetingType as IiosMeetingType | undefined,
      interactionId: body.interactionId,
      targetActorId: body.targetActorId,
    });
  }

  @Get('meetings')
  async list(@Headers('authorization') auth?: string) {
    return this.calendar.listMeetings(this.principal(auth));
  }

  @Get('meetings/:id')
  async get(@Param('id') id: string, @Headers('authorization') auth?: string) {
    return this.calendar.getMeeting(id, this.principal(auth));
  }

  @Post('meetings/:id/consent')
  async consent(@Param('id') id: string, @Body() body: ConsentDto, @Headers('authorization') auth?: string) {
    return this.calendar.setConsent(id, body.actorRefId, body.status as IiosConsentStatus, this.principal(auth));
  }

  @Post('meetings/:id/transcript')
  async transcript(@Param('id') id: string, @Headers('authorization') auth?: string) {
    return this.calendar.generateTranscript(id, this.principal(auth));
  }

  @Post('meetings/:id/summarize')
  async summarize(@Param('id') id: string, @Headers('authorization') auth?: string) {
    return this.calendar.summarize(id, this.principal(auth));
  }

  @Get('meetings/:id/action-items')
  async actionItems(@Param('id') id: string, @Headers('authorization') auth?: string) {
    return this.calendar.listActionItems(id, this.principal(auth));
  }

  @Post('providers')
  async connect(@Headers('authorization') auth?: string) {
    return this.adapter.connectProvider(this.principal(auth));
  }

  @Post('providers/:id/sync')
  async sync(@Param('id') id: string, @Headers('authorization') auth?: string) {
    this.principal(auth);
    return this.adapter.syncOnce(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);
  }
}
