import {
  Controller,
  Get,
  Param,
  Query,
  NotFoundException,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiQuery,
} from '@nestjs/swagger';
import { FeatsService } from './feats.service';

@ApiTags('Feats')
@ApiBearerAuth()
@Controller('feats')
export class FeatsController {
  constructor(private readonly featsService: FeatsService) {}

  @Get()
  @ApiOperation({ summary: 'Search and filter feats' })
  @ApiResponse({ status: 200, description: 'List of feats with pagination' })
  @ApiQuery({ name: 'query', required: false, description: 'Search term' })
  @ApiQuery({ name: 'featType', required: false, description: 'Feat type (General, Skill, Class, Ancestry, Archetype)' })
  @ApiQuery({ name: 'className', required: false, description: 'Class name for class feats' })
  @ApiQuery({ name: 'ancestryName', required: false, description: 'Ancestry name for ancestry feats' })
  @ApiQuery({ name: 'skillName', required: false, description: 'Skill name for skill feats' })
  @ApiQuery({ name: 'minLevel', required: false, type: Number, description: 'Minimum feat level' })
  @ApiQuery({ name: 'maxLevel', required: false, type: Number, description: 'Maximum feat level' })
  @ApiQuery({ name: 'rarity', required: false, description: 'Rarity (Common, Uncommon, Rare, Unique)' })
  @ApiQuery({ name: 'traits', required: false, description: 'Comma-separated traits' })
  @ApiQuery({ name: 'page', required: false, type: Number, description: 'Page number (default: 1)' })
  @ApiQuery({ name: 'limit', required: false, type: Number, description: 'Items per page (default: 20)' })
  async search(
    @Query('query') query?: string,
    @Query('featType') featType?: string,
    @Query('className') className?: string,
    @Query('ancestryName') ancestryName?: string,
    @Query('skillName') skillName?: string,
    @Query('minLevel') minLevel?: string,
    @Query('maxLevel') maxLevel?: string,
    @Query('rarity') rarity?: string,
    @Query('traits') traits?: string,
    @Query('page') page?: string,
    @Query('limit') limit?: string,
  ) {
    return this.featsService.search({
      query,
      featType,
      className,
      ancestryName,
      skillName,
      minLevel: minLevel ? parseInt(minLevel, 10) : undefined,
      maxLevel: maxLevel ? parseInt(maxLevel, 10) : undefined,
      rarity,
      traits: traits ? traits.split(',').map((t) => t.trim()) : undefined,
      page: page ? parseInt(page, 10) : 1,
      limit: limit ? parseInt(limit, 10) : 20,
    });
  }

  @Get('types')
  @ApiOperation({ summary: 'Get all feat types' })
  @ApiResponse({ status: 200, description: 'List of feat types' })
  async getFeatTypes() {
    return this.featsService.getFeatTypes();
  }

  @Get('classes')
  @ApiOperation({ summary: 'Get all classes that have class feats' })
  @ApiResponse({ status: 200, description: 'List of class names' })
  async getClasses() {
    return this.featsService.getClasses();
  }

  @Get('ancestries')
  @ApiOperation({ summary: 'Get all ancestries that have ancestry feats' })
  @ApiResponse({ status: 200, description: 'List of ancestry names' })
  async getAncestries() {
    return this.featsService.getAncestries();
  }

  @Get('traits')
  @ApiOperation({ summary: 'Get all unique traits from feats' })
  @ApiResponse({ status: 200, description: 'List of traits' })
  async getTraits() {
    return this.featsService.getTraits();
  }

  @Get(':id')
  @ApiOperation({ summary: 'Get feat by ID' })
  @ApiResponse({ status: 200, description: 'Feat details' })
  @ApiResponse({ status: 404, description: 'Feat not found' })
  async findById(@Param('id') id: string) {
    const feat = await this.featsService.findById(id);
    if (!feat) {
      throw new NotFoundException('Feat not found');
    }
    return feat;
  }

  @Get('by-name/:name')
  @ApiOperation({ summary: 'Get feat by name' })
  @ApiResponse({ status: 200, description: 'Feat details' })
  @ApiResponse({ status: 404, description: 'Feat not found' })
  async findByName(@Param('name') name: string) {
    const feat = await this.featsService.findByName(decodeURIComponent(name));
    if (!feat) {
      throw new NotFoundException('Feat not found');
    }
    return feat;
  }
}
