// steps.controller.ts
import {
  Controller,
  Post,
  Get,
  Put,
  Param,
  Body,
  UseInterceptors,
  UploadedFile,
  BadRequestException,
  Delete,
  UseGuards,
  Req,
  Patch,
} from '@nestjs/common';
import { StepsService } from './steps.service';
import { CreateStepDto } from './dto/create-step.dto';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { extname } from 'path';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { UpdateStepDto } from './dto/update-step.dto';
import { RolesGuard } from '../auth/roles.guard';
import { Roles } from '../auth/roles.decorator';
import type { StepType } from './step.entity';

function videoFileName(_req, file, cb) {
  const unique = Date.now() + '-' + Math.round(Math.random() * 1e9);
  cb(null, unique + extname(file.originalname)); // e.g. 1695111111-123.mp4
}
function videoFileFilter(_req, file, cb) {
  // allow mp4, mov, mkv, webm
  const ok = [
    'video/mp4',
    'video/quicktime',
    'video/x-matroska',
    'video/webm',
  ].includes(file.mimetype);
  if (!ok) return cb(new BadRequestException('Invalid video format'), false);
  cb(null, true);
}

@Controller('lessons/:lessonId/steps')
export class StepsController {
  constructor(private stepsService: StepsService) { }

  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles('trainer', 'admin')
  // TEXT and QUESTION via JSON
  @Post()
  createJson(@Param('lessonId') lessonId: string, @Body() dto: CreateStepDto) {
    return this.stepsService.createStep(+lessonId, dto);
  }

  // VIDEO via multipart/form-data
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles('trainer', 'admin')
  @Post('video')
  @UseInterceptors(
    FileInterceptor('file', {
      storage: diskStorage({
        destination: './uploads/videos',
        filename: videoFileName,
      }),
      fileFilter: videoFileFilter,
      limits: { fileSize: 1024 * 1024 * 500 }, // 500MB
    }),
  )
  async uploadVideo(
    @Param('lessonId') lessonId: string,
    @UploadedFile() file: Express.Multer.File,
    @Body('title') title?: string,
    @Body('type') type?: StepType,
    @Body('teleprompterText') teleprompterText?: string,
  ) {
    if (!file) throw new BadRequestException('Video file is required');
    return this.stepsService.createVideoStep(+lessonId, {
      title: title || 'Video',
      videoPath: `/uploads/videos/${file.filename}`, // public path
      type: type,
      teleprompterText: teleprompterText,
    });
  }

  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles('trainer', 'admin')
  @Put('/:stepId/video')
  @UseInterceptors(
    FileInterceptor('file', {
      storage: diskStorage({
        destination: './uploads/videos',
        filename: videoFileName,
      }),
      fileFilter: videoFileFilter,
      limits: { fileSize: 1024 * 1024 * 500 }, // 500MB
    }),
  )
  async updateVideo(
    @Param('lessonId') lessonId: string,
    @Param('stepId') stepId: string,
    @UploadedFile() file?: Express.Multer.File,
    @Body('title') title?: string,
    @Body('teleprompterText') teleprompterText?: string,
  ) {
    if (!file && !title && !teleprompterText) {
      throw new BadRequestException(
        'Either a video file, title, or teleprompter text must be provided',
      );
    }

    return this.stepsService.updateVideoStep(+lessonId, +stepId, {
      title: title,
      videoPath: file ? `/uploads/videos/${file.filename}` : undefined,
      teleprompterText: teleprompterText,
    });
  }

  @UseGuards(JwtAuthGuard)
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles('trainer', 'admin')
  @Put(':stepId')
  update(
    @Param('lessonId') lessonId: string,
    @Param('stepId') stepId: string,
    @Body() dto: UpdateStepDto,
    @Req() req,
  ) {
    return this.stepsService.updateStep(+lessonId, +stepId, dto, req.user);
  }

  @UseGuards(JwtAuthGuard)
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles('trainer', 'admin')
  @Delete(':stepId')
  remove(
    @Param('lessonId') lessonId: string,
    @Param('stepId') stepId: string,
    @Req() req,
  ) {
    return this.stepsService.deleteStep(+lessonId, +stepId, req.user);
  }

  @Patch('reorder')
  @UseGuards(JwtAuthGuard, RolesGuard)
  @Roles('trainer', 'admin')
  reorder(
    @Param('lessonId') lessonId: string,
    @Body() body: { order: { stepId: number; order: number }[] },
  ) {
    return this.stepsService.reorderSteps(+lessonId, body.order);
  }
}
