import {
  Controller,
  Get,
  Post,
  Body,
  Param,
  UseInterceptors,
  UploadedFile,
  Query,
  UnauthorizedException,
  Req,
  Patch,
  UseGuards,
} from '@nestjs/common';
import { PlaceService } from './place.service';
import { CreatePlaceDateTradDto } from './dto/create-place-date.dto';
import { ApiBearerAuth, ApiBody, ApiConsumes, ApiParam, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';
import { Roles } from 'src/auth/role.decorator';
import { ALL_ROLES } from 'src/shared/enum/admin-role.enum';
import { fileInterceptor } from 'src/shared/interceptors/file-save.interceptor';
import { FileValidationPipe } from 'src/shared/pipe/file-validation.pipe';
import { LANGUAGES } from 'src/shared/enum/languages.enum';
import { CustomAdminRequest } from 'src/auth/admin/interface/customAdminReq';
import { UpdatePlaceReqDto } from './dto/update-place.req.dto';
import { AuthAdminGuard } from 'src/auth/admin/authAdmin.guard';
import { GetPlaceDto } from './dto/get-place.dto';

@Controller('place')
@ApiTags('Place')
export class PlaceController {
  constructor(private readonly placeService: PlaceService) {}

  @ApiBody({ type: CreatePlaceDateTradDto })
  @ApiConsumes('multipart/form-data')
  @ApiResponse({ type: GetPlaceDto, status: 201, description: 'Created' })
  @UseGuards(AuthAdminGuard)
  @Roles([ALL_ROLES.ADMIN])
  @ApiBearerAuth('jwt')
  @Post()
  @UseInterceptors(fileInterceptor('image', 'static/places/', ['.jpg', '.jpeg', '.png']))
  async create(
    @UploadedFile(new FileValidationPipe()) file,
    @Body() createPlaceDto: CreatePlaceDateTradDto,
    @Req() req: CustomAdminRequest,
  ) {
    try {
      if (req.admin.idTown.townId != createPlaceDto.idTown) {
        throw new UnauthorizedException('This is not your assigned town');
      }
      createPlaceDto.image = file;
      await this.placeService.create(createPlaceDto);
      return { message: 'Place created successfully' };
    } catch (e) {
      throw e;
    }
  }

  @ApiQuery({ name: 'lang', type: String })
  @ApiParam({ name: 'idTown', type: Number })
  @Get('/town/:idTown/place')
  async findAll(@Param('idTown') idTown: number, @Query('lang') lang: string) {
    try {
      return this.placeService.findAllByTown(idTown, lang as LANGUAGES);
    } catch (e) {
      throw e;
    }
  }

  @Get(':idPlace')
  @ApiQuery({ name: 'lang', type: String })
  findOne(@Param('idPlace') idPlace: number, @Query('lang') lang: string) {
    return this.placeService.findOneAndTradAndAvailable(idPlace, lang as LANGUAGES);
  }

  @Patch(':idPlace')
  @UseGuards(AuthAdminGuard)
  @Roles([ALL_ROLES.ADMIN])
  @ApiBearerAuth('jwt')
  @ApiConsumes('multipart/form-data')
  @ApiBody({ type: CreatePlaceDateTradDto })
  @UseInterceptors(fileInterceptor('image', 'static/places/', ['.jpg', '.jpeg', '.png']))
  async update(
    @UploadedFile(new FileValidationPipe()) file,
    @Body() updatePlaceReqDto: UpdatePlaceReqDto,
    @Param('idPlace') idPlace: number,
    @Req() req: CustomAdminRequest,
  ) {
    try {
      if (req.admin.idTown.townId != updatePlaceReqDto.idTown) {
        throw new UnauthorizedException('This is not your assigned town');
      }
      updatePlaceReqDto.image = file;
      await this.placeService.update(idPlace, updatePlaceReqDto);
      return { message: 'Place updated successfully' };
    } catch (e) {
      throw e;
    }
  }
}
