import { Controller, Get, Post, Body, Patch, Param, Delete, Query, UseGuards } from '@nestjs/common';
import { CouponService } from '../providers/coupon.service';
import { CreateCouponDto } from '../dto/create-coupon.dto';
import { UpdateCouponDto } from '../dto/update-coupon.dto';
import { FindCouponsDto } from '../dto/find-coupons.dto';
import {
  ApiTags,
  ApiOperation,
  ApiCreatedResponse,
  ApiOkResponse,
  ApiNotFoundResponse,
  ApiQuery,
  ApiBody,
  ApiParam,
  ApiBearerAuth,
  ApiHeader,
} from '@nestjs/swagger';
import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard';
import { RestId } from 'src/common/decorators';
import { AuthGuard } from 'src/modules/auth/guards/auth.guard';
import { API_HEADER_SLUG } from 'src/common/constants';
import { Permission } from 'src/common/enums/permission.enum';
import { Permissions } from 'src/common/decorators/permissions.decorator';

@ApiTags('coupons')
@Controller()
export class CouponController {
  constructor(private readonly couponService: CouponService) { }

  @UseGuards(AuthGuard)
  @ApiBearerAuth()
  @Get('public/coupons/me')
  @ApiOperation({ summary: 'Get paginated list of restaurant coupons' })
  @ApiHeader(API_HEADER_SLUG)
  @ApiQuery({ name: 'page', required: false, type: Number })
  @ApiQuery({ name: 'limit', required: false, type: Number })
  @ApiQuery({ name: 'search', required: false, type: String })
  @ApiQuery({ name: 'orderBy', required: false, type: String })
  @ApiQuery({ name: 'order', required: false, enum: ['asc', 'desc'] })
  @ApiQuery({ name: 'type', required: false, enum: ['PERCENTAGE', 'FIXED'] })
  @ApiQuery({ name: 'isActive', required: false, type: Boolean })
  getMyCoupons(@Query() dto: FindCouponsDto, @RestId() restId: string) {
    return this.couponService.findAll(restId, dto);
  }
  /*** Admin ***/
  @UseGuards(AdminAuthGuard)
  @ApiBearerAuth()
  @Permissions(Permission.MANAGE_COUPONS)
  @Post('admin/coupons')
  @ApiOperation({ summary: 'Create a new coupon' })
  @ApiCreatedResponse({ description: 'The coupon has been successfully created.', type: CreateCouponDto })
  @ApiBody({ type: CreateCouponDto })
  create(@Body() createCouponDto: CreateCouponDto, @RestId() restId: string) {
    return this.couponService.create(restId, createCouponDto);
  }

  @UseGuards(AdminAuthGuard)
  @ApiBearerAuth()
  @Permissions(Permission.MANAGE_COUPONS)
  @Get('admin/coupons')
  @ApiOperation({ summary: 'Get a paginated list of coupons' })
  @ApiQuery({ name: 'page', required: false, type: Number })
  @ApiQuery({ name: 'limit', required: false, type: Number })
  @ApiQuery({ name: 'search', required: false, type: String })
  @ApiQuery({ name: 'orderBy', required: false, type: String })
  @ApiQuery({ name: 'order', required: false, enum: ['asc', 'desc'] })
  @ApiQuery({ name: 'type', required: false, enum: ['PERCENTAGE', 'FIXED'] })
  @ApiQuery({ name: 'isActive', required: false, type: Boolean })
  findAll(@Query() dto: FindCouponsDto, @RestId() restId: string) {
    return this.couponService.findAll(restId, dto);
  }

  @UseGuards(AdminAuthGuard)
  @ApiBearerAuth()
  @Permissions(Permission.MANAGE_COUPONS)
  @Get('admin/coupons/:id')
  @ApiOperation({ summary: 'Get a coupon by id' })
  @ApiParam({ name: 'id', required: true })
  findById(@Param('id') id: string) {
    return this.couponService.findById(id);
  }

  @UseGuards(AdminAuthGuard)
  @ApiBearerAuth()
  @Permissions(Permission.MANAGE_COUPONS)
  @Patch('admin/coupons/:id')
  @ApiOperation({ summary: 'Update a coupon' })
  @ApiParam({ name: 'id', required: true })
  @ApiBody({ type: UpdateCouponDto })
  update(@Param('id') id: string, @Body() updateCouponDto: UpdateCouponDto) {
    return this.couponService.update(id, updateCouponDto);
  }

  @UseGuards(AdminAuthGuard)
  @ApiBearerAuth()
  @Permissions(Permission.MANAGE_COUPONS)
  @Delete('admin/coupons/:id')
  @ApiOperation({ summary: 'Delete (soft) a coupon' })
  @ApiParam({ name: 'id', required: true })
  remove(@Param('id') id: string) {
    return this.couponService.remove(id);
  }

  @UseGuards(AdminAuthGuard)
  @ApiBearerAuth()
  @Permissions(Permission.MANAGE_COUPONS)
  @Get('admin/coupons/generate-code')
  @ApiOperation({ summary: 'generate a coupon code' })
  generateCouponCode(@RestId() restId: string) {
    return this.couponService.generateCouponCode(restId);
  }
}
