import {
  Body,
  Controller,
  Get,
  HttpCode,
  HttpStatus,
  Param,
  Post,
  UseGuards,
} from '@nestjs/common';
import { ApiBearerAuth, ApiParam, ApiQuery, ApiTags } from '@nestjs/swagger';
import { JwtAuthGuard } from '../auth/jwt/jwt.guard';
import { PermissionsGuard } from '../auth/permission/permissions.guard';
import { User } from '../../utils/decorators/user.decorator';
import { successfulResult } from '../../utils';

import { FreewayTollService } from './freeway-toll.service';
import { PayFreewayTollInquiryDto } from './dto/pay-freeway-toll-inquiry.dto';
import { CreateFreewayTollRequestDto } from './dto/create-freeway-toll-request.dto';
import { UserEntity } from '../user/entities/user.entity';
import { Page } from '../../utils/decorators/page.decorator';
import { Limit } from '../../utils/decorators/limit.decorator';
import { Filter } from '../../utils/decorators/filter.decorator';
import { Sort } from '../../utils/decorators/sort.decorator';
import { Permissions } from '../auth/permission/permissions.decorator';
import { PermissionsType } from '../role/entities/permission.entity';
import {
  FreewayTollClient,
  FreewayTollStatus,
} from './entities/freeway-toll.entity';

@ApiTags('Freeway Toll')
@Controller('freeway-tolls')
export class FreewayTollController {
  constructor(private freewayTollService: FreewayTollService) {}

  /**
   * -------------------------------------------------------
   * POST /freeway-tolls/request/me
   */
  @Post('/request/me')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @HttpCode(HttpStatus.CREATED)
  async addRequest(
    @Body() dto: CreateFreewayTollRequestDto,
    @User() user: UserEntity,
  ) {
    const data = await this.freewayTollService.addRequest(dto, user);
    return successfulResult(
      ['درخواست استعلام عوارض آزادراهی، باموفقیت ثبت شد'],
      data,
    );
  }

  /**
   * -------------------------------------------------------
   * POST /freeway-tolls/pay-inquiry/me
   */
  @Post('/pay-inquiry/me')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  async payInquiry(
    @Body() dto: PayFreewayTollInquiryDto,
    @User() user: UserEntity,
  ) {
    const data = await this.freewayTollService.payInquiry(dto, user);
    return successfulResult(
      [data.paid ? '???????????????????????' : 'در حال ارسال به بانک'],
      data,
    );
  }

  /**
   * -------------------------------------------------------
   * GET /freeway-tolls/1/do-inquiry/me
   * call from front or payment service
   */
  @Get('/:id/do-inquiry/me')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @ApiParam({ name: 'id', type: 'number' })
  async doInquiry(
    @Param('id') freewayTollId: number,
    @User() user: UserEntity,
  ) {
    const data = await this.freewayTollService.doInquiry(
      null,
      freewayTollId,
      user,
    );
    return successfulResult([], data);
  }

  /**
   * -------------------------------------------------------
   * POST /freeway-tolls/1/pay-bills/me
   */
  @Post('/:id/pay-bills/me')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @ApiParam({ name: 'id', type: 'number' })
  async payBills(@Param('id') freewayTollId, @User() user: UserEntity) {
    const data = await this.freewayTollService.payBills(freewayTollId, user);
    return successfulResult(['در حال ارسال به بانک'], data);
  }

  /**
   * -------------------------------------------------------
   * POST /freeway-tolls/1/pay-result-bills/me
   */
  @Get('/:id/pay-result-bills/me')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @ApiParam({ name: 'id', type: 'number' })
  async payBillResult(@Param('id') freewayTollId, @User() user: UserEntity) {
    const data = await this.freewayTollService.payResultBills(
      freewayTollId,
      user,
    );
    return successfulResult([], data);
  }

  /**
   * -------------------------------------------------------
   * GET /freeway-tolls/admin
   */
  @Get('/admin')
  @ApiQuery({ name: 'user_id', required: false })
  @ApiQuery({ name: 'car_id', required: false })
  @ApiQuery({ name: 'status', required: false, enum: FreewayTollStatus })
  @ApiQuery({ name: 'client', required: false, enum: FreewayTollClient })
  @ApiQuery({
    name: 'date',
    required: false,
    description: 'e.g. gte:2022-04-16[and]lte:2022-04-16',
  })
  @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_FREEWAY_TOLL)
  async getAllForAdmin(
    @Page() page,
    @Limit() limit,
    @Sort() sorts,
    @Filter([
      ['user_id', 'userId'],
      ['car_id', 'carId'],
      'status',
      'client',
      ['date', 'createdAt', 'DATE'],
    ])
    filters,
  ) {
    const data = await this.freewayTollService.getAll(
      page,
      limit,
      filters,
      sorts,
    );
    return successfulResult([], data);
  }

  /**
   * -------------------------------------------------------
   * GET /freeway-tolls/me
   */
  @Get('/me')
  @ApiQuery({ name: 'car_id', required: false })
  @ApiQuery({ name: 'status', required: false, enum: FreewayTollStatus })
  @ApiQuery({
    name: 'date',
    required: false,
    description: 'e.g. gte:2022-04-16[and]lte:2022-04-16',
  })
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.GET_FREEWAY_TOLL)
  async getAll(
    @Page() page,
    @Limit() limit,
    @Sort() sorts,
    @Filter([['car_id', 'carId'], 'status', ['date', 'createdAt', 'DATE']])
    filters,
  ) {
    const data = await this.freewayTollService.getAll(
      page,
      limit,
      filters,
      sorts,
    );
    return successfulResult([], data);
  }

  /**
   * -------------------------------------------------------
   * GET /freeway-tolls/1/admin
   */
  @Get('/:id/admin')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.GET_FREEWAY_TOLL)
  async getByIdForAdmin(@Param('id') id: number) {
    const data = await this.freewayTollService.getById(id);
    return successfulResult([], data);
  }

  /**
   * -------------------------------------------------------
   * GET /freeway-tolls/1/me
   */
  @Get('/:id/me')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.GET_FREEWAY_TOLL)
  async getById(@Param('id') id: number) {
    const data = await this.freewayTollService.getById(id);
    return successfulResult([], data);
  }
}
