import {
  Body,
  Controller,
  Delete,
  Get,
  HttpCode,
  HttpStatus,
  Param,
  Post,
  Put,
  UseGuards,
} from '@nestjs/common';
import { ApiBearerAuth, ApiQuery, ApiTags } from '@nestjs/swagger';
import { ErrorService } from 'src/error/error.service';
import { sort } from 'src/utils/sort';
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 { AttributeService } from './attribute.service';
import { AttributeSortDto } from './dto/attribute-sort.dto';
import { CreateAttributeOptionDto } from './dto/create-attribute-option.dto';
import { CreateAttributeDto } from './dto/create-attribute.dto';
import { UpdateAttributeDto } from './dto/update-attribute.dto';
import { AttributeEntity } from './entities/attribute.entity';

@ApiTags('Attribute')
@Controller('attributes')
export class AttributeController {
  constructor(
    private attributeService: AttributeService,
    private error: ErrorService,
  ) {}

  /**
   * -------------------------------------------------------
   * PUT /attributes/sort/admin
   */
  @Put('sort/admin')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.SORT_ATTRIBUTE)
  async sort(@Body() dto: AttributeSortDto) {
    const result = await sort(AttributeEntity.name, dto.id, dto.action);

    if (!result) {
      return this.error.unprocessableEntity(['داده جایگزینی یافت نشد']);
    }

    return successfulResult(['داده مورد نظر با موفقیت مرتب شد']);
  }

  /**
   * -------------------------------------------------------
   * PUT /attributes/1/admin
   */
  @Put(':id/admin')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.UPDATE_ATTRIBUTE)
  async updateAttribute(
    @Param('id') id: number,
    @Body() dto: UpdateAttributeDto,
  ) {
    await this.attributeService.updateAttribute(id, dto);
    return successfulResult(['ویژگی مورد نظر با موفقیت آپدیت شد']);
  }

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

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

  /**
   * -------------------------------------------------------
   * GET /attributes/admin
   */
  @Get('admin')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.GET_ATTRIBUTE)
  @ApiQuery({ name: 'product_id', required: false })
  @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' })
  async list(
    @Page() page,
    @Limit() limit,
    @Sort() sorts,
    @Filter([
      'deleted',
      ['product_id', 'productAttributeOptionMappings.productId'],
    ])
    filters,
  ) {
    const data = await this.attributeService.getAll(
      page,
      limit,
      filters,
      sorts,
    );
    return successfulResult([], data);
  }

  /**
   * -------------------------------------------------------
   * POST /attributes/admin
   */
  @Post('admin')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.ADD_ATTRIBUTE)
  @HttpCode(HttpStatus.CREATED)
  async addAttribute(@Body() dto: CreateAttributeDto) {
    const data = await this.attributeService.addAttribute(dto);
    return successfulResult([' ویژگی جدید، باموفقیت اضافه شد'], data);
  }

  /**
   * -------------------------------------------------------
   * POST /attributes/option/admin
   */
  @Post('option/admin')
  @ApiBearerAuth()
  @UseGuards(JwtAuthGuard, PermissionsGuard)
  @Permissions(PermissionsType.ADD_ATTRIBUTE)
  @HttpCode(HttpStatus.CREATED)
  async addAttributeOption(@Body() dto: CreateAttributeOptionDto) {
    const data = await this.attributeService.addAttributeOption(dto);
    return successfulResult(
      [' آپشن جدید به ویژگی موردنظر، باموفقیت اضافه شد'],
      data,
    );
  }

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