import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  UseInterceptors,
  UploadedFile,
  ParseFilePipe,
  MaxFileSizeValidator,
  FileTypeValidator,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiConsumes,
  ApiBody,
} from '@nestjs/swagger';
import { BattleMapsService } from './battle-maps.service';
import { CreateBattleMapDto, UpdateBattleMapDto } from './dto';
import { CurrentUser } from '../../common/decorators/current-user.decorator';

@ApiTags('Battle')
@ApiBearerAuth()
@Controller('campaigns/:campaignId/battle-maps')
export class BattleMapsController {
  constructor(private readonly battleMapsService: BattleMapsService) {}

  @Get()
  @ApiOperation({ summary: 'Get all battle maps for a campaign' })
  @ApiResponse({ status: 200, description: 'List of battle maps' })
  async findAll(
    @Param('campaignId') campaignId: string,
    @CurrentUser('id') userId: string,
  ) {
    return this.battleMapsService.findAll(campaignId, userId);
  }

  @Get(':mapId')
  @ApiOperation({ summary: 'Get a specific battle map' })
  @ApiResponse({ status: 200, description: 'Battle map details' })
  async findOne(
    @Param('campaignId') campaignId: string,
    @Param('mapId') mapId: string,
    @CurrentUser('id') userId: string,
  ) {
    return this.battleMapsService.findOne(campaignId, mapId, userId);
  }

  @Post()
  @UseInterceptors(FileInterceptor('image'))
  @ApiOperation({ summary: 'Upload a new battle map' })
  @ApiConsumes('multipart/form-data')
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        name: { type: 'string' },
        gridSizeX: { type: 'number' },
        gridSizeY: { type: 'number' },
        gridOffsetX: { type: 'number' },
        gridOffsetY: { type: 'number' },
        image: { type: 'string', format: 'binary' },
      },
      required: ['name', 'image'],
    },
  })
  @ApiResponse({ status: 201, description: 'Battle map created' })
  async create(
    @Param('campaignId') campaignId: string,
    @Body() dto: CreateBattleMapDto,
    @UploadedFile(
      new ParseFilePipe({
        validators: [
          new MaxFileSizeValidator({ maxSize: 10 * 1024 * 1024 }), // 10MB
          new FileTypeValidator({ fileType: /^image\/(png|jpeg|jpg|webp)$/ }),
        ],
      }),
    )
    image: Express.Multer.File,
    @CurrentUser('id') userId: string,
  ) {
    return this.battleMapsService.create(campaignId, dto, image, userId);
  }

  @Put(':mapId')
  @ApiOperation({ summary: 'Update battle map settings' })
  @ApiResponse({ status: 200, description: 'Battle map updated' })
  async update(
    @Param('campaignId') campaignId: string,
    @Param('mapId') mapId: string,
    @Body() dto: UpdateBattleMapDto,
    @CurrentUser('id') userId: string,
  ) {
    return this.battleMapsService.update(campaignId, mapId, dto, userId);
  }

  @Delete(':mapId')
  @ApiOperation({ summary: 'Delete a battle map' })
  @ApiResponse({ status: 200, description: 'Battle map deleted' })
  async delete(
    @Param('campaignId') campaignId: string,
    @Param('mapId') mapId: string,
    @CurrentUser('id') userId: string,
  ) {
    return this.battleMapsService.delete(campaignId, mapId, userId);
  }
}
