import {
  Body,
  Controller,
  Delete,
  HttpCode,
  Param,
  ParseIntPipe,
  Patch,
  Post,
  Request,
  Get,
  UnauthorizedException,
} from '@nestjs/common';
import { Throttle } from '@nestjs/throttler';
import { CreateFlyerSelectionDto } from './dto/create-flyer-selection.dto';
import { CreateFlyerSelectionBulkDto } from './dto/create-flyer-selection-bulk.dto';
import { FlyerSelectionResponse } from './dto/flyer-selection.response';
import { UpdateFlyerSelectionDto } from './dto/update-flyer-selection.dto';
import { FlyerSelectionService } from './flyer-selection.service';
import { PlanToShoppingListDto } from './dto/plan-to-shopping-list.dto';

@Controller('flyer-sessions/:sessionId/selections')
export class FlyerSelectionController {
  constructor(private readonly flyerSelectionService: FlyerSelectionService) {}

  @Get()
  async list(
    @Param('sessionId', ParseIntPipe) sessionId: number,
    @Request() req?: any,
  ): Promise<FlyerSelectionResponse[]> {
    const userId = this.getUserId(req);
    return this.flyerSelectionService.listBySession(sessionId, userId);
  }

  @Post()
  @HttpCode(200)
  @Throttle({ default: { ttl: 60_000, limit: 20 } })
  async create(
    @Param('sessionId', ParseIntPipe) sessionId: number,
    @Body() dto: CreateFlyerSelectionDto,
    @Request() req?: any,
  ): Promise<FlyerSelectionResponse> {
    const userId = this.getUserId(req);
    return this.flyerSelectionService.create(sessionId, userId, dto);
  }

  @Post('bulk')
  @HttpCode(200)
  @Throttle({ default: { ttl: 60_000, limit: 10 } })
  async createMany(
    @Param('sessionId', ParseIntPipe) sessionId: number,
    @Body() dto: CreateFlyerSelectionBulkDto,
    @Request() req?: any,
  ): Promise<FlyerSelectionResponse[]> {
    const userId = this.getUserId(req);
    return this.flyerSelectionService.createMany(sessionId, userId, dto.items);
  }

  @Patch(':selectionId')
  @HttpCode(200)
  @Throttle({ default: { ttl: 60_000, limit: 30 } })
  async update(
    @Param('sessionId', ParseIntPipe) sessionId: number,
    @Param('selectionId', ParseIntPipe) selectionId: number,
    @Body() dto: UpdateFlyerSelectionDto,
    @Request() req?: any,
  ): Promise<FlyerSelectionResponse> {
    const userId = this.getUserId(req);
    return this.flyerSelectionService.update(sessionId, selectionId, userId, dto);
  }

  @Delete(':selectionId')
  @HttpCode(204)
  @Throttle({ default: { ttl: 60_000, limit: 20 } })
  async remove(
    @Param('sessionId', ParseIntPipe) sessionId: number,
    @Param('selectionId', ParseIntPipe) selectionId: number,
    @Request() req?: any,
  ): Promise<void> {
    const userId = this.getUserId(req);
    await this.flyerSelectionService.remove(sessionId, selectionId, userId);
  }

  @Post('plan-to-shopping-list')
  @HttpCode(200)
  @Throttle({ default: { ttl: 60_000, limit: 20 } })
  async planToShoppingList(
    @Param('sessionId', ParseIntPipe) sessionId: number,
    @Body() dto: PlanToShoppingListDto,
    @Request() req?: any,
  ): Promise<{ created: number; updated: number; processedSelectionIds: number[] }> {
    const userId = this.getUserId(req);
    return this.flyerSelectionService.planToShoppingList(sessionId, userId, dto.itemIds);
  }

  private getUserId(req?: any): number {
    const userId =
      typeof req?.user?.id === 'number'
        ? req.user.id
        : typeof req?.user?.userId === 'number'
          ? req.user.userId
          : undefined;
    if (!userId) {
      throw new UnauthorizedException('Kunde inte identifiera användaren.');
    }
    return userId;
  }
}
