import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
  Query,
  Req,
  UploadedFiles,
  UseInterceptors,
} from '@nestjs/common';
import { FilesInterceptor } from '@nestjs/platform-express';
import {
  ApiConsumes,
  ApiOperation,
  ApiResponse,
  ApiTags,
} from '@nestjs/swagger';
import { PaginationDto } from '../../common/dto/pagination.dto';
import { ImageProcessingPipe } from '../../common/pipes/image-processing.pipe';
import { CreateTrainingDto } from './dto/create-training.dto';
import { TrainingStatisticsFilterDto } from './dto/training-statistics-filter.dto';
import { UpdateTrainingDto } from './dto/update-training.dto';
import { TrainingService } from './training.service';

@ApiTags('training')
@Controller('training')
export class TrainingController {
  constructor(private readonly trainingService: TrainingService) { }

  // @Public()
  // @Get('export/:id')
  // @ApiOperation({ summary: 'Export training template' })
  // @ApiResponse({
  //   status: 200,
  //   description: 'Return training template.',
  //   content: { 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': { schema: { type: 'string', format: 'binary' } } }
  // })
  // @Header('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
  // @Header('Content-Disposition', 'attachment; filename=export_osp.xlsx')
  // async exportTemplate(@Param('id') id: string) {
  //   if (!Number(id)) {
  //     throw new Error('ID is required');
  //   }
  //   const data = await this.trainingService.exportTemplate(Number(id));
  //   return new StreamableFile(data);
  // }

  // ========== //
  @Get()
  @ApiOperation({
    summary: 'Get all training records with pagination and filters',
  })
  @ApiResponse({
    status: 200,
    description: 'Return paginated training records.',
  })
  async findAll(@Req() req: Request, @Query() paginationDto: PaginationDto) {
    const user = (req as any).user;

    const result = await this.trainingService.findAll(paginationDto, { role: user?.roles[0], id: user?.id });
    return {
      message: 'Training records fetched successfully',
      data: result.data,
      meta: result.meta,
    };
  }

  // ========== //
  @Get('statistics')
  @ApiOperation({ summary: 'Get training statistics' })
  @ApiResponse({ status: 200, description: 'Return training statistics.' })
  async getStatistics(@Query() filterDto: TrainingStatisticsFilterDto) {
    const data = await this.trainingService.getStatistics(filterDto);
    return { message: 'Training statistics fetched successfully', data };
  }

  // ========== //
  @Get(':id')
  @ApiOperation({ summary: 'Get a training record by ID' })
  @ApiResponse({ status: 200, description: 'Return the training record.' })
  @ApiResponse({ status: 404, description: 'Training record not found.' })
  async findOne(@Param('id') id: string) {
    const data = await this.trainingService.findOne(+id);
    return { message: 'Training record fetched successfully', data };
  }

  // ========== //
  @Post()
  @UseInterceptors(FilesInterceptor('files', 3))
  @ApiConsumes('multipart/form-data')
  @ApiOperation({ summary: 'Create a new training record' })
  @ApiResponse({
    status: 201,
    description: 'Training record created successfully.',
  })
  async create(
    @Req() req: Request,
    @Body() createTrainingDto: CreateTrainingDto,
    @UploadedFiles(ImageProcessingPipe) files: Express.Multer.File[],
  ) {
    const userId = (req as any).user?.id;
    const data = await this.trainingService.create(
      createTrainingDto,
      files,
      userId,
    );
    return { message: 'Training record created successfully', data };
  }

  // ========== //
  @Patch(':id')
  @UseInterceptors(FilesInterceptor('files', 3))
  @ApiConsumes('multipart/form-data')
  @ApiOperation({ summary: 'Update a training record' })
  @ApiResponse({
    status: 200,
    description: 'Training record updated successfully.',
  })
  @ApiResponse({ status: 404, description: 'Training record not found.' })
  async update(
    @Req() req: Request,
    @Param('id') id: string,
    @Body() updateTrainingDto: UpdateTrainingDto,
    @UploadedFiles(ImageProcessingPipe) files: Express.Multer.File[],
  ) {
    const userId = (req as any).user?.id;
    const data = await this.trainingService.update(
      +id,
      updateTrainingDto,
      files,
      userId,
    );
    return { message: 'Training record updated successfully', data };
  }

  // ========== //
  @Delete(':id')
  @ApiOperation({ summary: 'Delete a training record' })
  @ApiResponse({
    status: 200,
    description: 'Training record deleted successfully.',
  })
  @ApiResponse({ status: 404, description: 'Training record not found.' })
  async remove(@Param('id') id: string) {
    return await this.trainingService.remove(+id);
  }
}
