import { Injectable, NotFoundException, ForbiddenException } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import * as fs from 'fs';
import * as path from 'path';

@Injectable()
export class FilesService {
  private uploadDir = 'uploads';

  constructor(private prisma: PrismaService) {
    // Ensure upload directory exists
    if (!fs.existsSync(this.uploadDir)) {
      fs.mkdirSync(this.uploadDir, { recursive: true });
    }
  }

  async saveFile(file: Express.Multer.File, uploaderId: number, timetableEntryId?: number) {
    return this.prisma.file.create({
      data: {
        filename: file.originalname,
        path: file.path,
        mimetype: file.mimetype,
        size: file.size,
        uploadedById: uploaderId,
        timetableEntryId: timetableEntryId ? Number(timetableEntryId) : null,
      },
      include: {
        uploadedBy: {
            select: {
                username: true,
                role: true
            }
        }
      }
    });
  }

  async findAllGeneral() {
    return this.prisma.file.findMany({
      where: { timetableEntryId: null },
      include: { uploadedBy: { select: { username: true, role: true } } },
      orderBy: { createdAt: 'desc' }
    });
  }

  async findByLesson(lessonId: number, userId: number, userRole: string) {
    const lessonIdNum = Number(lessonId);
    if (userRole === 'Lehrer') {
      return this.prisma.file.findMany({
        where: { timetableEntryId: lessonIdNum },
        include: { uploadedBy: { select: { id: true, username: true, role: true } } },
        orderBy: { createdAt: 'desc' }
      });
    } else {
      return this.prisma.file.findMany({
        where: {
          timetableEntryId: lessonIdNum,
          OR: [
            { uploadedBy: { role: 'Lehrer' } },
            { uploadedById: userId }
          ]
        },
        include: { uploadedBy: { select: { id: true, username: true, role: true } } },
        orderBy: { createdAt: 'desc' }
      });
    }
  }

  async getFileEntity(id: number) {
      const file = await this.prisma.file.findUnique({ where: { id } });
      if (!file) throw new NotFoundException('File not found');
      return file;
  }

  async deleteFile(id: number, userId: number, userRole: string) {
     const file = await this.prisma.file.findUnique({ where: { id } });
     if (!file) throw new NotFoundException('File not found');
     
     if (userRole !== 'Lehrer' && file.uploadedById !== userId) {
         throw new ForbiddenException('You can only delete your own files');
     }
     
     await this.prisma.file.delete({ where: { id } });
     try {
         if (fs.existsSync(file.path)) {
            fs.unlinkSync(file.path);
         }
     } catch (e) {
         console.error("Failed to delete file from disk", e);
     }
     return { success: true };
  }
}