import {
  BadRequestException,
  Body,
  Controller,
  Get,
  Param,
  Post,
  Query,
} from '@nestjs/common';
import { ProgressService } from './progress.service';
import { SyncProgressDto, UpsertProgressDto } from './dto/progress.dto';

@Controller('api/v1/progress')
export class ProgressController {
  constructor(private readonly progressService: ProgressService) {}

  @Post()
  async upsert(@Body() dto: UpsertProgressDto) {
    const data = await this.progressService.upsertProgress(
      dto.anonymousSessionId,
      dto.entityType,
      dto.entityId,
      dto.progressJson,
    );
    return { success: true, message: 'Progress saved', data };
  }

  /** Uploads everything recorded while offline in one round trip. */
  @Post('sync')
  async sync(@Body() dto: SyncProgressDto) {
    const synced = await this.progressService.syncBatch(dto.anonymousSessionId, dto.entries);
    const data = await this.progressService.getSessionProgress(dto.anonymousSessionId);
    return { success: true, message: `Synced ${synced} entries`, data, meta: { synced } };
  }

  @Get()
  async find(
    @Query('sessionId') sessionId: string,
    @Query('entityType') entityType?: string,
    @Query('entityId') entityId?: string,
  ) {
    if (!sessionId) throw new BadRequestException('sessionId is required');

    if (entityType && entityId) {
      const data = await this.progressService.getProgress(
        sessionId,
        entityType,
        Number(entityId),
      );
      return { success: true, message: 'Success', data };
    }

    const data = await this.progressService.getSessionProgress(sessionId);
    return { success: true, message: 'Success', data };
  }

  /** Percentages the Home and Progress screens render. */
  @Get('summary')
  async summary(@Query('sessionId') sessionId: string) {
    if (!sessionId) throw new BadRequestException('sessionId is required');
    const data = await this.progressService.summarise(sessionId);
    return { success: true, message: 'Success', data };
  }

  @Get('session/:sessionId')
  async sessionProgress(@Param('sessionId') sessionId: string) {
    const data = await this.progressService.getSessionProgress(sessionId);
    return { success: true, message: 'Success', data };
  }
}
