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

export async function listEvents(req: AuthRequest, res: Response): Promise<void> {
  try {
    const events = await prisma.event.findMany({
      where: { organizerId: req.organizerId },
      include: {
        _count: { select: { attendees: true } },
      },
      orderBy: { createdAt: 'desc' },
    });

    res.json(events);
  } catch (error) {
    console.error('listEvents error:', error);
    res.status(500).json({ error: 'Failed to fetch events' });
  }
}

export async function createEvent(req: AuthRequest, res: Response): Promise<void> {
  try {
    const { name, description, startDate, endDate, location, locationLat, locationLng, isPaid, requireApproval, sendEmailNotif, sendWhatsappNotif, bannerUrl, fromName, fromEmail } = req.body;

    if (!name || !startDate) {
      res.status(400).json({ error: 'Name and start date are required' });
      return;
    }

    const event = await prisma.event.create({
      data: {
        organizerId: req.organizerId!,
        name,
        description,
        startDate: new Date(startDate),
        endDate: endDate ? new Date(endDate) : null,
        location,
        locationLat,
        locationLng,
        isPaid: isPaid ?? false,
        requireApproval: requireApproval ?? false,
        sendEmailNotif: sendEmailNotif ?? true,
        sendWhatsappNotif: sendWhatsappNotif ?? true,
        bannerUrl,
        fromName,
        fromEmail,
      },
    });

    // Auto-create "General" ticket category
    await prisma.ticketCategory.create({
      data: {
        eventId: event.id,
        name: 'General',
        price: 0,
        order: 0,
      },
    });

    const fullEvent = await prisma.event.findUnique({
      where: { id: event.id },
      include: { categories: true },
    });

    res.status(201).json(fullEvent);
  } catch (error) {
    console.error('createEvent error:', error);
    res.status(500).json({ error: 'Failed to create event' });
  }
}

export async function getEvent(req: AuthRequest, res: Response): Promise<void> {
  try {
    const event = await prisma.event.findFirst({
      where: { id: req.params.id, organizerId: req.organizerId },
      include: { categories: { orderBy: { order: 'asc' } } },
    });

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

    res.json(event);
  } catch (error) {
    console.error('getEvent error:', error);
    res.status(500).json({ error: 'Failed to fetch event' });
  }
}

export async function updateEvent(req: AuthRequest, res: Response): Promise<void> {
  try {
    const existing = await prisma.event.findFirst({
      where: { id: req.params.id, organizerId: req.organizerId },
    });

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

    const { name, description, startDate, endDate, location, locationLat, locationLng, isPaid, requireApproval, sendEmailNotif, sendWhatsappNotif, bannerUrl, fromName, fromEmail, qrConfig, googleSheetUrl, googleSheetMapping, emailTriggers, rsvpFormConfig } = req.body;

    const event = await prisma.event.update({
      where: { id: req.params.id },
      data: {
        ...(name !== undefined && { name }),
        ...(description !== undefined && { description }),
        ...(startDate !== undefined && { startDate: new Date(startDate) }),
        ...(endDate !== undefined && { endDate: endDate ? new Date(endDate) : null }),
        ...(location !== undefined && { location }),
        ...(locationLat !== undefined && { locationLat }),
        ...(locationLng !== undefined && { locationLng }),
        ...(isPaid !== undefined && { isPaid }),
        ...(requireApproval !== undefined && { requireApproval }),
        ...(sendEmailNotif !== undefined && { sendEmailNotif }),
        ...(sendWhatsappNotif !== undefined && { sendWhatsappNotif }),
        ...(bannerUrl !== undefined && { bannerUrl }),
        ...(fromName !== undefined && { fromName }),
        ...(fromEmail !== undefined && { fromEmail }),
        ...(qrConfig !== undefined && { qrConfig }),
        ...(googleSheetUrl !== undefined && { googleSheetUrl }),
        ...(googleSheetMapping !== undefined && { googleSheetMapping }),
        ...(emailTriggers !== undefined && { emailTriggers }),
        ...(rsvpFormConfig !== undefined && { rsvpFormConfig }),
      },
    });

    res.json(event);
  } catch (error) {
    console.error('updateEvent error:', error);
    res.status(500).json({ error: 'Failed to update event' });
  }
}

export async function deleteEvent(req: AuthRequest, res: Response): Promise<void> {
  try {
    const existing = await prisma.event.findFirst({
      where: { id: req.params.id, organizerId: req.organizerId },
    });

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

    await prisma.event.delete({ where: { id: req.params.id } });

    res.json({ message: 'Event deleted' });
  } catch (error) {
    console.error('deleteEvent error:', error);
    res.status(500).json({ error: 'Failed to delete event' });
  }
}

export async function getEventSummary(req: AuthRequest, res: Response): Promise<void> {
  try {
    const event = await prisma.event.findFirst({
      where: { id: req.params.id, organizerId: req.organizerId },
    });

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

    const totalRsvps = await prisma.attendee.count({
      where: { eventId: req.params.id },
    });

    const arrived = await prisma.attendee.count({
      where: { eventId: req.params.id, attendance: 'ARRIVED' },
    });

    const notArrived = await prisma.attendee.count({
      where: { eventId: req.params.id, attendance: 'NOT_ARRIVED' },
    });

    res.json({ totalRsvps, arrived, notArrived });
  } catch (error) {
    console.error('getEventSummary error:', error);
    res.status(500).json({ error: 'Failed to fetch event summary' });
  }
}
