import { Body, Delete, Path, Post, Put, Request, Response, Route, Security, SuccessResponse, Tags, UploadedFile } from 'tsoa';
import { ValidationError } from '../middleware/errorHandler';
import { ChaptersLessonService } from '../services/ChaptersLesson.service';
import {
    UploadedFileInfo,
    CreateLessonResponse,
    UpdateLessonResponse,
    VideoOperationResponse,
    AttachmentOperationResponse,
    DeleteAttachmentResponse,
    YouTubeVideoResponse,
    SetYouTubeVideoBody,
} from '../types/ChaptersLesson.typs';

const chaptersLessonService = new ChaptersLessonService();

@Route('api/instructors/courses/{courseId}/chapters/{chapterId}/lessons')
@Tags('Lessons - File Upload')
export class LessonsController {

    /**
     * อัพโหลดวิดีโอใหม่ให้บทเรียน (ครั้งแรก)
     * Upload video to lesson (first time)
     * 
     * @param courseId Course ID
     * @param chapterId Chapter ID  
     * @param lessonId Lesson ID
     * @param video ไฟล์วิดีโอ (required)
     */
    @Post('{lessonId}/video')
    @Security('jwt', ['instructor'])
    @SuccessResponse('200', 'Video uploaded successfully')
    @Response('400', 'Validation error - Video already exists')
    @Response('401', 'Unauthorized')
    @Response('403', 'Forbidden')
    @Response('404', 'Lesson not found')
    public async uploadVideo(
        @Request() request: any,
        @Path() courseId: number,
        @Path() chapterId: number,
        @Path() lessonId: number,
        @UploadedFile() video: Express.Multer.File
    ): Promise<VideoOperationResponse> {
        const token = request.headers.authorization?.replace('Bearer ', '');
        if (!token) throw new ValidationError('No token provided');

        if (!video) {
            throw new ValidationError('Video file is required');
        }

        const videoInfo: UploadedFileInfo = {
            originalname: video.originalname,
            mimetype: video.mimetype,
            size: video.size,
            buffer: video.buffer,
        };

        return await chaptersLessonService.uploadVideo({
            token,
            course_id: courseId,
            lesson_id: lessonId,
            video: videoInfo,
        });
    }

    /**
     * อัพเดต (เปลี่ยน) วิดีโอของบทเรียน
     * Update (replace) video in lesson
     * 
     * @param courseId Course ID
     * @param chapterId Chapter ID
     * @param lessonId Lesson ID
     * @param video ไฟล์วิดีโอใหม่ (required)
     */
    @Put('{lessonId}/video')
    @Security('jwt', ['instructor'])
    @SuccessResponse('200', 'Video updated successfully')
    @Response('400', 'Validation error')
    @Response('401', 'Unauthorized')
    @Response('403', 'Forbidden')
    @Response('404', 'Lesson not found')
    public async updateVideo(
        @Request() request: any,
        @Path() courseId: number,
        @Path() chapterId: number,
        @Path() lessonId: number,
        @UploadedFile() video: Express.Multer.File
    ): Promise<VideoOperationResponse> {
        const token = request.headers.authorization?.replace('Bearer ', '');
        if (!token) throw new ValidationError('No token provided');

        if (!video) {
            throw new ValidationError('Video file is required');
        }

        const videoInfo: UploadedFileInfo = {
            originalname: video.originalname,
            mimetype: video.mimetype,
            size: video.size,
            buffer: video.buffer,
        };

        return await chaptersLessonService.updateVideo({
            token,
            course_id: courseId,
            lesson_id: lessonId,
            video: videoInfo,
        });
    }

    /**
     * อัพโหลดไฟล์แนบทีละไฟล์
     * Upload a single attachment to lesson
     * 
     * @param courseId Course ID
     * @param chapterId Chapter ID
     * @param lessonId Lesson ID
     * @param attachment ไฟล์แนบ (required)
     */
    @Post('{lessonId}/attachments')
    @Security('jwt', ['instructor'])
    @SuccessResponse('200', 'Attachment uploaded successfully')
    @Response('400', 'Validation error')
    @Response('401', 'Unauthorized')
    @Response('403', 'Forbidden')
    @Response('404', 'Lesson not found')
    public async uploadAttachment(
        @Request() request: any,
        @Path() courseId: number,
        @Path() chapterId: number,
        @Path() lessonId: number,
        @UploadedFile() attachment: Express.Multer.File
    ): Promise<AttachmentOperationResponse> {
        const token = request.headers.authorization?.replace('Bearer ', '');
        if (!token) throw new ValidationError('No token provided');

        if (!attachment) {
            throw new ValidationError('Attachment file is required');
        }

        const attachmentInfo: UploadedFileInfo = {
            originalname: attachment.originalname,
            mimetype: attachment.mimetype,
            size: attachment.size,
            buffer: attachment.buffer,
        };

        return await chaptersLessonService.uploadAttachment({
            token,
            course_id: courseId,
            lesson_id: lessonId,
            attachment: attachmentInfo,
        });
    }

    /**
     * ลบไฟล์แนบทีละไฟล์
     * Delete a single attachment from lesson
     * 
     * @param courseId Course ID
     * @param chapterId Chapter ID
     * @param lessonId Lesson ID
     * @param attachmentId Attachment ID
     */
    @Delete('{lessonId}/attachments/{attachmentId}')
    @Security('jwt', ['instructor'])
    @SuccessResponse('200', 'Attachment deleted successfully')
    @Response('400', 'Validation error')
    @Response('401', 'Unauthorized')
    @Response('403', 'Forbidden')
    @Response('404', 'Attachment not found')
    public async deleteAttachment(
        @Request() request: any,
        @Path() courseId: number,
        @Path() chapterId: number,
        @Path() lessonId: number,
        @Path() attachmentId: number
    ): Promise<DeleteAttachmentResponse> {
        const token = request.headers.authorization?.replace('Bearer ', '');
        if (!token) throw new ValidationError('No token provided');

        return await chaptersLessonService.deleteAttachment({
            token,
            course_id: courseId,
            lesson_id: lessonId,
            attachment_id: attachmentId,
        });
    }

    /**
     * ตั้งค่าวิดีโอ YouTube ให้บทเรียน (แทนที่วิดีโอเดิมถ้ามี)
     * Set YouTube video for a lesson (replaces existing video if any)
     * 
     * @param courseId Course ID
     * @param chapterId Chapter ID
     * @param lessonId Lesson ID
     * @param body YouTube video info
     */
    @Post('{lessonId}/youtube-video')
    @Security('jwt', ['instructor'])
    @SuccessResponse('200', 'YouTube video set successfully')
    @Response('400', 'Validation error')
    @Response('401', 'Unauthorized')
    @Response('403', 'Forbidden')
    @Response('404', 'Lesson not found')
    public async setYouTubeVideo(
        @Request() request: any,
        @Path() courseId: number,
        @Path() chapterId: number,
        @Path() lessonId: number,
        @Body() body: SetYouTubeVideoBody
    ): Promise<YouTubeVideoResponse> {
        const token = request.headers.authorization?.replace('Bearer ', '');
        if (!token) throw new ValidationError('No token provided');

        if (!body.youtube_video_id) {
            throw new ValidationError('YouTube video ID is required');
        }
        if (!body.video_title) {
            throw new ValidationError('Video title is required');
        }

        return await chaptersLessonService.setYouTubeVideo({
            token,
            course_id: courseId,
            lesson_id: lessonId,
            youtube_video_id: body.youtube_video_id,
            video_title: body.video_title,
        });
    }
}
