import {
  BadRequestException,
  Body,
  Controller,
  Delete,
  Get,
  Param,
  ParseIntPipe,
  Post,
  Put,
  Query,
} from '@nestjs/common';
import { CasesService } from './cases.service';
import { CreateCaseDto } from './dto/create-case.dto';
import { UpdateCaseDto } from './dto/update-case.dto';
import { CaseEntryDto } from './cases.controller';

/**
 * Learner case log (sections F2/H3 of the workbook). Cases created here belong
 * to an anonymous session and are never visible to other learners.
 */
@Controller('api/v1/cases')
export class LearnerCasesController {
  constructor(private readonly casesService: CasesService) {}

  /** Teaching cases the content team published, shared by all learners. */
  @Get('published')
  async published() {
    const data = await this.casesService.findPublished();
    return { success: true, message: 'Success', data };
  }

  @Get()
  async mine(@Query('sessionId') sessionId: string) {
    if (!sessionId) throw new BadRequestException('sessionId is required');
    const data = await this.casesService.findBySession(sessionId);
    return { success: true, message: 'Success', data };
  }

  @Post()
  async create(@Body() dto: CreateCaseDto) {
    if (!dto.anonymousSessionId) {
      throw new BadRequestException('anonymousSessionId is required');
    }
    const data = await this.casesService.create(dto);
    return { success: true, message: 'Case saved', data };
  }

  @Get(':id')
  async findById(
    @Param('id', ParseIntPipe) id: number,
    @Query('sessionId') sessionId: string,
  ) {
    const caseEntity = await this.casesService.findById(id);
    if (!caseEntity) return { success: false, message: 'Case not found' };

    const isOwn = caseEntity.anonymousSessionId === sessionId;
    const isPublishedTeachingCase =
      !caseEntity.anonymousSessionId && caseEntity.status === 'PUBLISHED';

    if (!isOwn && !isPublishedTeachingCase) {
      return { success: false, message: 'Case not found' };
    }
    return { success: true, message: 'Success', data: caseEntity };
  }

  @Put(':id')
  async update(
    @Param('id', ParseIntPipe) id: number,
    @Query('sessionId') sessionId: string,
    @Body() dto: UpdateCaseDto,
  ) {
    if (!sessionId) throw new BadRequestException('sessionId is required');
    const data = await this.casesService.updateOwned(id, sessionId, dto);
    return { success: true, message: 'Case updated', data };
  }

  @Post(':id/entries')
  async addEntry(
    @Param('id', ParseIntPipe) id: number,
    @Query('sessionId') sessionId: string,
    @Body() dto: CaseEntryDto,
  ) {
    if (!sessionId) throw new BadRequestException('sessionId is required');
    await this.casesService.updateOwned(id, sessionId, {});
    const data = await this.casesService.addEntry(id, dto.payload);
    return { success: true, message: 'Case entry added', data };
  }

  @Delete(':id')
  async delete(
    @Param('id', ParseIntPipe) id: number,
    @Query('sessionId') sessionId: string,
  ) {
    if (!sessionId) throw new BadRequestException('sessionId is required');
    const success = await this.casesService.deleteOwned(id, sessionId);
    return { success, message: success ? 'Case deleted' : 'Case not found' };
  }
}
