import {
  Body,
  Controller,
  Get,
  Post,
  Param,
  Put,
  UseGuards,
  Header,
  Res,
  Delete,
} from '@nestjs/common';
import { ApiBearerAuth, ApiQuery, ApiTags } from '@nestjs/swagger';
import { Response } from 'express';
import { successfulResult } from '../../utils';
import { Filter } from '../../utils/decorators/filter.decorator';
import { Limit } from '../../utils/decorators/limit.decorator';
import { Page } from '../../utils/decorators/page.decorator';
import { Sort } from '../../utils/decorators/sort.decorator';
import { JwtAuthGuard } from '../auth/jwt/jwt.guard';
import { Permissions } from '../auth/permission/permissions.decorator';
import { PermissionsGuard } from '../auth/permission/permissions.guard';
import { PermissionsType } from '../role/entities/permission.entity';
import { DiscountService } from './discount.service';
import { CreateDiscountDto } from './dto/create-discount.dto';
import { UpdateDiscountDto } from './dto/update-discount.dto';
import { CalculateDiscountDto } from './dto/calculate-discount.dto';
import { User } from '../../utils/decorators/user.decorator';
import { UserEntity } from '../user/entities/user.entity';

@ApiTags('Discount')
@Controller('discounts')
export class DiscountController {
  constructor(private discountService: DiscountService) {}

  /**
   * -------------------------------------------------------
   */
  @Get('export/excel/admin')
  @Header('Content-Type', 'text/xlsx')
  @ApiQuery({
    name: 'end_date',
    required: false,
    description: 'e.g. gte:2022-04-16',
  })
  @ApiQuery({
    name: 'start_date',
    required: false,
    description: 'e.g. lte:2022-04-16',
  })
  @ApiQuery({
    name: 'section',
    required: false,
    description: 'service | product | both',
  })
  @ApiQuery({
    name: 'customer_id',
    required: false,
    description: 'e.g. 1',
  })
  @ApiQuery({
    name: 'name',
    required: false,
    description: 'e.g. like:%abc%',
  })
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.EXPORT_EXCEL_FROM_DISCOUNT)
  async exportExcel(
    @Res() res: Response,
    @Filter([
      ['start_date', 'startDate', 'DATE'],
      ['end_date', 'endDate', 'DATE'],
      'section',
      'name',
      ['customer_id', 'customerId'],
    ])
    filters,
  ) {
    const result = await this.discountService.exportExcel(filters);
    return res.download(`${result}`);
  }

  /**
   * -------------------------------------------------------
   */
  @Get('statistic/admin')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.GET_DISCOUNT_STATISTICS)
  async statistic() {
    const data = await this.discountService.statistic();
    return successfulResult([], data);
  }

  /**
   * -------------------------------------------------------
   */
  @Get(':id/admin')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.GET_DISCOUNT)
  async info(@Param('id') id: number) {
    const data = await this.discountService.getById(id);
    return successfulResult([], data);
  }

  /**
   * -------------------------------------------------------
   */
  @Get('admin')
  @ApiQuery({
    name: 'end_date',
    required: false,
    description: 'e.g. gte:2022-04-16',
  })
  @ApiQuery({
    name: 'start_date',
    required: false,
    description: 'e.g. lte:2022-04-16',
  })
  @ApiQuery({
    name: 'section',
    required: false,
    description: 'service | product | both',
  })
  @ApiQuery({
    name: 'customer_id',
    required: false,
    description: 'e.g. 1',
  })
  @ApiQuery({
    name: 'name',
    required: false,
    description: 'e.g. like:%abc%',
  })
  @ApiQuery({ name: 'deleted', required: false, description: 'e.g. 1' })
  @ApiQuery({ name: 'sort', required: false, description: 'e.g. id:desc' })
  @ApiQuery({ name: 'limit', required: false, description: 'Default: 20' })
  @ApiQuery({ name: 'page', required: false, description: 'Default: 1' })
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.GET_DISCOUNT)
  async list(
    @Page() page,
    @Limit(50) limit,
    @Sort() sorts,
    @Filter([
      ['start_date', 'startDate', 'DATE'],
      ['end_date', 'endDate', 'DATE'],
      'section',
      'name',
      'deleted',
      ['customer_id', 'customerId'],
    ])
    filters,
  ) {
    const data = await this.discountService.getAll(page, limit, filters, sorts);
    return successfulResult([], data);
  }

  /**
   * -------------------------------------------------------
   */
  @Put('admin')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.UPDATE_DISCOUNT)
  async updateById(@Body() dto: UpdateDiscountDto) {
    await this.discountService.updateById(dto);
    return successfulResult(['کد تخفیف با موفقیت آپدیت شد']);
  }

  /**
   * -------------------------------------------------------
   */
  @Post('admin')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.ADD_DISCOUNT)
  async create(@Body() dto: CreateDiscountDto) {
    await this.discountService.create(dto);
    return successfulResult(['کد تخفیف(های) جدید با موفقیت ایجاد شد']);
  }

  /**
   * -------------------------------------------------------
   */
  @Post('calculate/me')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard)
  async calculate(@Body() dto: CalculateDiscountDto, @User() user: UserEntity) {
    const result = await this.discountService.calDiscountByCouponCode(
      dto.code,
      dto.isService,
      dto.orderTotal || 0,
      dto.totalWage || 0,
      dto.runValidations,
      user,
    );
    return successfulResult([], result);
  }

  /**
   * -------------------------------------------------------
   * DELETE /discount/1
   */
  @Delete('/:id/admin')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.DELETE_DISCOUNT)
  async deleteDiscount(@Param('id') id: number) {
    await this.discountService.deleteDiscount(id);
    return successfulResult(['تخفیف موردنظر با موفقیت حذف شد']);
  }
}
