import {
  Controller,
  Post,
  Get,
  Param,
  Body,
  Put,
  Query,
  UseInterceptors,
  UploadedFile,
} from '@nestjs/common';
import { TempTrainersService } from './temp_trainers.service';
import { TempTrainers } from './entities/temp_trainers.entity';
import { Public } from '../auth/public.decorator';
import { DataSource } from 'typeorm';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { extname } from 'path';
import {
  ApiBearerAuth,
  ApiTags,
  ApiBody,
  ApiParam,
  ApiQuery,
  ApiOperation,
  ApiConsumes,
} from '@nestjs/swagger';

@ApiTags('tempTrainers')
@ApiBearerAuth('access-token')
@Controller('tempTrainers')
export class TempTrainersController {
  constructor(
    private readonly tempTrainersService: TempTrainersService,
    private dataSource: DataSource,
  ) {}

  @Public()
  @Get('applications')
  @ApiOperation({ summary: 'List Trainer Applications' })
  @ApiQuery({ name: 'page', required: false, type: Number })
  @ApiQuery({ name: 'limit', required: false, type: Number })
  @ApiQuery({
    name: 'status',
    required: false,
    enum: ['pending', 'approved', 'rejected'],
  })
  async list(
    @Query('page') page = 1,
    @Query('limit') limit = 10,
    @Query('status') status?: 'pending' | 'approved' | 'rejected',
  ) {
    // console.log(page, limit, status);
    const data = await this.tempTrainersService.getApplications(
      Number(page),
      Number(limit),
      status,
    );
    // console.log(data);
    return { success: true, data };
  }
  /**
   * Get all specializations by type
   * Example: GET /tempTrainers/specializations?type=tech
   */
  @Public()
  @Get('specializations')
  @ApiOperation({ summary: 'Get Specializations' })
  @ApiQuery({ name: 'type', enum: ['tech', 'nontech'] })
  async getSpecializations(@Query('type') type: 'tech' | 'nontech') {
    const data = await this.tempTrainersService.getSpecializationsByType(type);
    // console.log(data);
    return { success: true, data };
  }

  /**
   * Candidate applies as trainer
   * POST /tempTrainers/apply
   */
  @Public()
  @Post('apply')
  @ApiOperation({ summary: 'Apply as Trainer' })
  @ApiConsumes('multipart/form-data')
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        fullName: { type: 'string' },
        email: { type: 'string', format: 'email' },
        phone: { type: 'string' },
        trainerType: { type: 'string', enum: ['tech', 'non-tech'] },
        specializationId: { type: 'number' },
        experienceYears: { type: 'number' },
        certifications: { type: 'string' },
        availabilityType: {
          type: 'string',
          enum: ['full-time', 'part-time', 'freelance', 'online', 'offline'],
        },
        trainerProfile: { type: 'string' },
        idProof: {
          type: 'string',
          format: 'binary',
        },
      },
      required: [
        'fullName',
        'email',
        'phone',
        'trainerType',
        'specializationId',
        'experienceYears',
        'idProof',
      ],
    },
  })
  @Post('apply')
  @UseInterceptors(
    FileInterceptor('idProof', {
      storage: diskStorage({
        destination: './uploads/trainer-id-proofs',
        filename: (req, file, cb) => {
          const uniqueSuffix =
            Date.now() + '-' + Math.round(Math.random() * 1e9);
          cb(null, uniqueSuffix + extname(file.originalname));
        },
      }),
      limits: { fileSize: 5 * 1024 * 1024 }, // 5MB limit
      fileFilter: (req, file, cb) => {
        if (!file.originalname.match(/\.(pdf|jpg|jpeg|png)$/i)) {
          return cb(
            new Error('Only PDF, JPG, JPEG, and PNG files are allowed!'),
            false,
          );
        }
        cb(null, true);
      },
    }),
  )
  async applyTrainer(
    @Body() body: Partial<TempTrainers>,
    @UploadedFile() file?: Express.Multer.File,
  ) {
    // console.log('=== Trainer Application Debug ===');
    // console.log('Body data:', body);
    // console.log('Body keys:', Object.keys(body));
    // console.log('File received:', file);
    // console.log(
    //   'File details:',
    //   file
    //     ? {
    //         fieldname: file.fieldname,
    //         originalname: file.originalname,
    //         path: file.path,
    //         size: file.size,
    //         mimetype: file.mimetype,
    //       }
    //     : 'No file',
    // );
    // console.log('File path:', file ? file.path : 'No file');

    // Add file path to the data if file was uploaded
    const applicationData = {
      ...body,
      idProof: file ? file.path.replace(/\\/g, '/') : null,
    };

    // console.log('Application data with idProof:', applicationData);
    // console.log('idProof in applicationData:', applicationData.idProof);

    const trainer =
      await this.tempTrainersService.createTrainerApplication(applicationData);
    return {
      success: true,
      message: 'Trainer application submitted successfully',
      data: trainer,
    };
  }

  /**
   * Approve trainer application
   * Put /tempTrainers/:id/approve
   */
  @Public()
  @Put(':id/approve')
  @ApiOperation({ summary: 'Approve Trainer Application' })
  @ApiParam({ name: 'id', type: Number })
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        remarks: { type: 'string', example: 'Qualified' },
      },
    },
  })
  async approve(@Param('id') id: number, @Body('remarks') remarks?: string) {
    return this.tempTrainersService.approveTrainer(Number(id), remarks);
  }

  /**
   * Reject trainer application
   * Put /tempTrainers/:id/reject
   */
  @Public()
  @Put(':id/reject')
  @ApiOperation({ summary: 'Reject Trainer Application' })
  @ApiParam({ name: 'id', type: Number })
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        remarks: { type: 'string', example: 'Not Qualified' },
      },
    },
  })
  async reject(@Param('id') id: number, @Body('remarks') remarks?: string) {
    return this.tempTrainersService.rejectTrainer(Number(id), remarks);
  }

  /**
   * Get one application by ID
   * GET /tempTrainers/:id
   */
  @Public()
  @Get(':id')
  @ApiOperation({ summary: 'Get Trainer Application by ID' })
  @ApiParam({ name: 'id', type: Number })
  async getTrainerById(@Param('id') id: number) {
    const trainer = await this.tempTrainersService.findById(Number(id));
    return {
      success: !!trainer,
      data: trainer ?? null,
    };
  }
}
