import {
  Controller,
  Get,
  Post,
  Put,
  Patch,
  Delete,
  Body,
  Param,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
} from '@nestjs/swagger';
import { BattleService } from './battle.service';
import { CreateBattleSessionDto, UpdateBattleSessionDto, CreateBattleTokenDto, UpdateBattleTokenDto } from './dto';
import { CurrentUser } from '../../common/decorators/current-user.decorator';

@ApiTags('Battle')
@ApiBearerAuth()
@Controller('campaigns/:campaignId/battles')
export class BattleController {
  constructor(private readonly battleService: BattleService) {}

  // ==========================================
  // BATTLE SESSIONS
  // ==========================================

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

  @Get(':sessionId')
  @ApiOperation({ summary: 'Get a specific battle session' })
  @ApiResponse({ status: 200, description: 'Battle session details' })
  async findSession(
    @Param('campaignId') campaignId: string,
    @Param('sessionId') sessionId: string,
    @CurrentUser('id') userId: string,
  ) {
    return this.battleService.findSession(campaignId, sessionId, userId);
  }

  @Post()
  @ApiOperation({ summary: 'Create a new battle session' })
  @ApiResponse({ status: 201, description: 'Battle session created' })
  async createSession(
    @Param('campaignId') campaignId: string,
    @Body() dto: CreateBattleSessionDto,
    @CurrentUser('id') userId: string,
  ) {
    return this.battleService.createSession(campaignId, dto, userId);
  }

  @Put(':sessionId')
  @ApiOperation({ summary: 'Update a battle session' })
  @ApiResponse({ status: 200, description: 'Battle session updated' })
  async updateSession(
    @Param('campaignId') campaignId: string,
    @Param('sessionId') sessionId: string,
    @Body() dto: UpdateBattleSessionDto,
    @CurrentUser('id') userId: string,
  ) {
    return this.battleService.updateSession(campaignId, sessionId, dto, userId);
  }

  @Delete(':sessionId')
  @ApiOperation({ summary: 'Delete a battle session' })
  @ApiResponse({ status: 200, description: 'Battle session deleted' })
  async deleteSession(
    @Param('campaignId') campaignId: string,
    @Param('sessionId') sessionId: string,
    @CurrentUser('id') userId: string,
  ) {
    return this.battleService.deleteSession(campaignId, sessionId, userId);
  }

  // ==========================================
  // BATTLE TOKENS
  // ==========================================

  @Post(':sessionId/tokens')
  @ApiOperation({ summary: 'Add a token to the battle' })
  @ApiResponse({ status: 201, description: 'Token added' })
  async addToken(
    @Param('campaignId') campaignId: string,
    @Param('sessionId') sessionId: string,
    @Body() dto: CreateBattleTokenDto,
    @CurrentUser('id') userId: string,
  ) {
    return this.battleService.addToken(campaignId, sessionId, dto, userId);
  }

  @Patch(':sessionId/tokens/:tokenId')
  @ApiOperation({ summary: 'Update a token' })
  @ApiResponse({ status: 200, description: 'Token updated' })
  async updateToken(
    @Param('campaignId') campaignId: string,
    @Param('sessionId') sessionId: string,
    @Param('tokenId') tokenId: string,
    @Body() dto: UpdateBattleTokenDto,
    @CurrentUser('id') userId: string,
  ) {
    return this.battleService.updateToken(campaignId, sessionId, tokenId, dto, userId);
  }

  @Delete(':sessionId/tokens/:tokenId')
  @ApiOperation({ summary: 'Remove a token from the battle' })
  @ApiResponse({ status: 200, description: 'Token removed' })
  async removeToken(
    @Param('campaignId') campaignId: string,
    @Param('sessionId') sessionId: string,
    @Param('tokenId') tokenId: string,
    @CurrentUser('id') userId: string,
  ) {
    return this.battleService.removeToken(campaignId, sessionId, tokenId, userId);
  }

  @Patch(':sessionId/tokens/:tokenId/move')
  @ApiOperation({ summary: 'Move a token on the map' })
  @ApiResponse({ status: 200, description: 'Token moved' })
  async moveToken(
    @Param('campaignId') campaignId: string,
    @Param('sessionId') sessionId: string,
    @Param('tokenId') tokenId: string,
    @Body() body: { positionX: number; positionY: number },
    @CurrentUser('id') userId: string,
  ) {
    return this.battleService.moveToken(campaignId, sessionId, tokenId, body.positionX, body.positionY, userId);
  }

  // ==========================================
  // INITIATIVE
  // ==========================================

  @Patch(':sessionId/tokens/:tokenId/initiative')
  @ApiOperation({ summary: 'Set token initiative' })
  @ApiResponse({ status: 200, description: 'Initiative set' })
  async setInitiative(
    @Param('campaignId') campaignId: string,
    @Param('sessionId') sessionId: string,
    @Param('tokenId') tokenId: string,
    @Body() body: { initiative: number },
    @CurrentUser('id') userId: string,
  ) {
    return this.battleService.setInitiative(campaignId, sessionId, tokenId, body.initiative, userId);
  }

  @Post(':sessionId/advance-round')
  @ApiOperation({ summary: 'Advance to the next round' })
  @ApiResponse({ status: 200, description: 'Round advanced' })
  async advanceRound(
    @Param('campaignId') campaignId: string,
    @Param('sessionId') sessionId: string,
    @CurrentUser('id') userId: string,
  ) {
    return this.battleService.advanceRound(campaignId, sessionId, userId);
  }
}
