import { Response } from 'express';
import { nanoid } from 'nanoid';
import path from 'path';
import { prisma } from '../config/database';
import { AuthRequest } from '../middleware/auth';
import { uploadToS3 } from '../config/s3';

export async function listGallery(req: AuthRequest, res: Response): Promise<void> {
  try {
    const { eventId } = req.params;

    const event = await prisma.event.findFirst({
      where: { id: eventId, organizerId: req.organizerId },
    });

    if (!event) {
      res.status(404).json({ error: 'Event not found' });
      return;
    }

    const categories = await prisma.photoCategory.findMany({
      where: { eventId },
      include: { photos: { orderBy: { uploadedAt: 'desc' } } },
      orderBy: { createdAt: 'asc' },
    });

    res.json(categories);
  } catch (error) {
    console.error('listGallery error:', error);
    res.status(500).json({ error: 'Failed to fetch gallery' });
  }
}

export async function createPhotoCategory(req: AuthRequest, res: Response): Promise<void> {
  try {
    const { eventId } = req.params;

    const event = await prisma.event.findFirst({
      where: { id: eventId, organizerId: req.organizerId },
    });

    if (!event) {
      res.status(404).json({ error: 'Event not found' });
      return;
    }

    const { name } = req.body;

    if (!name) {
      res.status(400).json({ error: 'Category name is required' });
      return;
    }

    const category = await prisma.photoCategory.create({
      data: { eventId, name },
    });

    res.status(201).json(category);
  } catch (error) {
    console.error('createPhotoCategory error:', error);
    res.status(500).json({ error: 'Failed to create photo category' });
  }
}

export async function deletePhotoCategory(req: AuthRequest, res: Response): Promise<void> {
  try {
    const { eventId, categoryId } = req.params;
    const event = await prisma.event.findFirst({ where: { id: eventId, organizerId: req.organizerId } });
    if (!event) { res.status(404).json({ error: 'Event not found' }); return; }

    const cat = await prisma.photoCategory.findFirst({ where: { id: categoryId, eventId } });
    if (!cat) { res.status(404).json({ error: 'Category not found' }); return; }

    await prisma.photoCategory.delete({ where: { id: categoryId } });
    res.json({ message: 'Category deleted' });
  } catch (error) {
    console.error('deletePhotoCategory error:', error);
    res.status(500).json({ error: 'Failed to delete category' });
  }
}

export async function uploadPhotos(req: AuthRequest, res: Response): Promise<void> {
  try {
    const { eventId, categoryId } = req.params;
    const event = await prisma.event.findFirst({ where: { id: eventId, organizerId: req.organizerId } });
    if (!event) { res.status(404).json({ error: 'Event not found' }); return; }

    const category = await prisma.photoCategory.findFirst({ where: { id: categoryId, eventId } });
    if (!category) { res.status(404).json({ error: 'Category not found' }); return; }

    const files = (req.files as Express.Multer.File[] | undefined) || [];
    if (files.length === 0) { res.status(400).json({ error: 'No files uploaded' }); return; }

    const created = await Promise.all(
      files.map(async (file) => {
        const ext = path.extname(file.originalname) || '.jpg';
        const key = `gallery/${eventId}/${categoryId}/${nanoid(10)}${ext}`;
        const url = await uploadToS3(file.buffer, key, file.mimetype);
        return prisma.photo.create({
          data: {
            categoryId,
            url,
            fileName: file.originalname,
            size: file.size,
          },
        });
      })
    );

    res.status(201).json(created);
  } catch (error) {
    console.error('uploadPhotos error:', error);
    res.status(500).json({ error: 'Failed to upload photos' });
  }
}

export async function deletePhoto(req: AuthRequest, res: Response): Promise<void> {
  try {
    const { eventId, photoId } = req.params;

    const event = await prisma.event.findFirst({
      where: { id: eventId, organizerId: req.organizerId },
    });

    if (!event) {
      res.status(404).json({ error: 'Event not found' });
      return;
    }

    const photo = await prisma.photo.findFirst({
      where: { id: photoId, category: { eventId } },
    });

    if (!photo) {
      res.status(404).json({ error: 'Photo not found' });
      return;
    }

    await prisma.photo.delete({ where: { id: photoId } });

    res.json({ message: 'Photo deleted' });
  } catch (error) {
    console.error('deletePhoto error:', error);
    res.status(500).json({ error: 'Failed to delete photo' });
  }
}
