import {
  Controller,
  Get,
  Post,
  Patch,
  Delete,
  Body,
  Param,
  Query,
  UseGuards,
  ParseUUIDPipe,
  HttpCode,
  HttpStatus,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiBearerAuth,
  ApiResponse,
  ApiParam,
} from '@nestjs/swagger';
import { CatalogService } from './catalog.service';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { RolesGuard } from '../auth/guards/roles.guard';
import { Roles, UserRole } from '../../common/decorators/roles.decorator';
import {
  CurrentUser,
  JwtPayload,
} from '../../common/decorators/current-user.decorator';
import {
  CreateCategoryDto,
  UpdateCategoryDto,
  CreateServiceDto,
  UpdateServiceDto,
  CreatePackageDto,
  UpdatePackageDto,
  FindCategoriesDto,
  FindServicesDto,
  FindPackagesDto,
} from './dto';

@ApiTags('Catalog')
@ApiBearerAuth()
@Controller('catalog')
@UseGuards(JwtAuthGuard)
export class CatalogController {
  constructor(private readonly catalogService: CatalogService) {}

  // ─── Categories ──────────────────────────────────────────────────

  @Get('categories')
  @ApiOperation({ summary: 'List service categories' })
  @ApiResponse({ status: 200, description: 'Paginated list of categories' })
  async findAllCategories(
    @CurrentUser() user: JwtPayload,
    @Query() query: FindCategoriesDto,
  ) {
    return this.catalogService.findAllCategories(user.clubId, query);
  }

  @Get('categories/:id')
  @ApiOperation({ summary: 'Get category by ID' })
  @ApiParam({ name: 'id', description: 'Category UUID' })
  @ApiResponse({ status: 200, description: 'Category details with services' })
  @ApiResponse({ status: 404, description: 'Category not found' })
  async findCategoryById(
    @CurrentUser() user: JwtPayload,
    @Param('id', ParseUUIDPipe) id: string,
  ) {
    return this.catalogService.findCategoryById(user.clubId, id);
  }

  @Post('categories')
  @UseGuards(RolesGuard)
  @Roles(UserRole.CLUB_ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Create a service category' })
  @ApiResponse({ status: 201, description: 'Category created' })
  async createCategory(
    @CurrentUser() user: JwtPayload,
    @Body() dto: CreateCategoryDto,
  ) {
    return this.catalogService.createCategory(user.clubId, dto);
  }

  @Patch('categories/:id')
  @UseGuards(RolesGuard)
  @Roles(UserRole.CLUB_ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Update a service category' })
  @ApiParam({ name: 'id', description: 'Category UUID' })
  @ApiResponse({ status: 200, description: 'Category updated' })
  @ApiResponse({ status: 404, description: 'Category not found' })
  async updateCategory(
    @CurrentUser() user: JwtPayload,
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: UpdateCategoryDto,
  ) {
    return this.catalogService.updateCategory(user.clubId, id, dto);
  }

  @Delete('categories/:id')
  @UseGuards(RolesGuard)
  @Roles(UserRole.CLUB_ADMIN, UserRole.SUPER_ADMIN)
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: 'Delete a service category' })
  @ApiParam({ name: 'id', description: 'Category UUID' })
  @ApiResponse({ status: 204, description: 'Category deleted' })
  @ApiResponse({ status: 404, description: 'Category not found' })
  async removeCategory(
    @CurrentUser() user: JwtPayload,
    @Param('id', ParseUUIDPipe) id: string,
  ) {
    return this.catalogService.removeCategory(user.clubId, id);
  }

  // ─── Services ────────────────────────────────────────────────────

  @Get('services')
  @ApiOperation({ summary: 'List services with filters' })
  @ApiResponse({ status: 200, description: 'Paginated list of services' })
  async findAllServices(
    @CurrentUser() user: JwtPayload,
    @Query() query: FindServicesDto,
  ) {
    return this.catalogService.findAllServices(user.clubId, query);
  }

  @Get('services/:id')
  @ApiOperation({ summary: 'Get service by ID' })
  @ApiParam({ name: 'id', description: 'Service UUID' })
  @ApiResponse({ status: 200, description: 'Service details with packages' })
  @ApiResponse({ status: 404, description: 'Service not found' })
  async findServiceById(
    @CurrentUser() user: JwtPayload,
    @Param('id', ParseUUIDPipe) id: string,
  ) {
    return this.catalogService.findServiceById(user.clubId, id);
  }

  @Post('services')
  @UseGuards(RolesGuard)
  @Roles(UserRole.CLUB_ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Create a service' })
  @ApiResponse({ status: 201, description: 'Service created' })
  async createService(
    @CurrentUser() user: JwtPayload,
    @Body() dto: CreateServiceDto,
  ) {
    return this.catalogService.createService(user.clubId, dto);
  }

  @Patch('services/:id')
  @UseGuards(RolesGuard)
  @Roles(UserRole.CLUB_ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Update a service' })
  @ApiParam({ name: 'id', description: 'Service UUID' })
  @ApiResponse({ status: 200, description: 'Service updated' })
  @ApiResponse({ status: 404, description: 'Service not found' })
  async updateService(
    @CurrentUser() user: JwtPayload,
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: UpdateServiceDto,
  ) {
    return this.catalogService.updateService(user.clubId, id, dto);
  }

  @Delete('services/:id')
  @UseGuards(RolesGuard)
  @Roles(UserRole.CLUB_ADMIN, UserRole.SUPER_ADMIN)
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: 'Delete a service' })
  @ApiParam({ name: 'id', description: 'Service UUID' })
  @ApiResponse({ status: 204, description: 'Service deleted' })
  @ApiResponse({ status: 404, description: 'Service not found' })
  async removeService(
    @CurrentUser() user: JwtPayload,
    @Param('id', ParseUUIDPipe) id: string,
  ) {
    return this.catalogService.removeService(user.clubId, id);
  }

  // ─── Packages ────────────────────────────────────────────────────

  @Get('packages')
  @ApiOperation({ summary: 'List packages with filters' })
  @ApiResponse({ status: 200, description: 'Paginated list of packages' })
  async findAllPackages(
    @CurrentUser() user: JwtPayload,
    @Query() query: FindPackagesDto,
  ) {
    return this.catalogService.findAllPackages(user.clubId, query);
  }

  @Get('packages/:id')
  @ApiOperation({ summary: 'Get package by ID' })
  @ApiParam({ name: 'id', description: 'Package UUID' })
  @ApiResponse({ status: 200, description: 'Package details' })
  @ApiResponse({ status: 404, description: 'Package not found' })
  async findPackageById(
    @CurrentUser() user: JwtPayload,
    @Param('id', ParseUUIDPipe) id: string,
  ) {
    return this.catalogService.findPackageById(user.clubId, id);
  }

  @Post('packages')
  @UseGuards(RolesGuard)
  @Roles(UserRole.CLUB_ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Create a package' })
  @ApiResponse({ status: 201, description: 'Package created' })
  @ApiResponse({ status: 404, description: 'Service not found' })
  async createPackage(
    @CurrentUser() user: JwtPayload,
    @Body() dto: CreatePackageDto,
  ) {
    return this.catalogService.createPackage(user.clubId, dto);
  }

  @Patch('packages/:id')
  @UseGuards(RolesGuard)
  @Roles(UserRole.CLUB_ADMIN, UserRole.SUPER_ADMIN)
  @ApiOperation({ summary: 'Update a package' })
  @ApiParam({ name: 'id', description: 'Package UUID' })
  @ApiResponse({ status: 200, description: 'Package updated' })
  @ApiResponse({ status: 404, description: 'Package not found' })
  async updatePackage(
    @CurrentUser() user: JwtPayload,
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: UpdatePackageDto,
  ) {
    return this.catalogService.updatePackage(user.clubId, id, dto);
  }

  @Delete('packages/:id')
  @UseGuards(RolesGuard)
  @Roles(UserRole.CLUB_ADMIN, UserRole.SUPER_ADMIN)
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: 'Delete a package' })
  @ApiParam({ name: 'id', description: 'Package UUID' })
  @ApiResponse({ status: 204, description: 'Package deleted' })
  @ApiResponse({ status: 404, description: 'Package not found' })
  async removePackage(
    @CurrentUser() user: JwtPayload,
    @Param('id', ParseUUIDPipe) id: string,
  ) {
    return this.catalogService.removePackage(user.clubId, id);
  }
}
