import { Router, Request, Response } from 'express';
import { prisma } from '../db/prisma';
import { requireAuth, requireRole } from '../middleware/auth';

const router = Router();

function incrementTitle(title: string): string {
  const match = title.match(/^(.*#)(\d+)(.*)$/);
  if (match) {
    const num = parseInt(match[2], 10);
    return `${match[1]}${num + 1}${match[3]}`;
  }
  return `${title} (copy)`;
}

router.get('/', async (req: Request, res: Response) => {
  try {
    const status = req.query.status as string | undefined;
    const admin = req.query.admin === 'true';
    const where: any = {};
    if (status) where.status = status;
    if (!admin) where.visibility = 'PUBLIC';

    const meetups = await prisma.meetup.findMany({
      where,
      orderBy: { date: 'asc' },
    });

    res.json(meetups);
  } catch (err) {
    console.error('List meetups error:', err);
    res.status(500).json({ error: 'Internal server error' });
  }
});

router.get('/:id', async (req: Request, res: Response) => {
  try {
    const meetup = await prisma.meetup.findUnique({
      where: { id: req.params.id as string },
    });

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

    res.json(meetup);
  } catch (err) {
    console.error('Get meetup error:', err);
    res.status(500).json({ error: 'Internal server error' });
  }
});

router.post(
  '/',
  requireAuth,
  requireRole(['ADMIN']),
  async (req: Request, res: Response) => {
    try {
      const { title, description, date, time, location, link, status, featured, imageId, visibility } =
        req.body;

      if (!title || !description || !date || !time || !location) {
        res
          .status(400)
          .json({ error: 'title, description, date, time, and location are required' });
        return;
      }

      const meetup = await prisma.meetup.create({
        data: {
          title,
          description,
          date,
          time,
          location,
          link: link || null,
          imageId: imageId || null,
          status: status || 'DRAFT',
          featured: featured || false,
          visibility: visibility || 'PUBLIC',
        },
      });

      res.status(201).json(meetup);
    } catch (err) {
      console.error('Create meetup error:', err);
      res.status(500).json({ error: 'Internal server error' });
    }
  }
);

router.post(
  '/bulk',
  requireAuth,
  requireRole(['ADMIN']),
  async (req: Request, res: Response) => {
    try {
      const { action, ids } = req.body as { action: string; ids: string[] };

      if (!action || !Array.isArray(ids) || ids.length === 0) {
        res.status(400).json({ error: 'action and ids are required' });
        return;
      }

      if (action === 'delete') {
        await prisma.meetup.deleteMany({ where: { id: { in: ids } } });
        res.json({ success: true, affected: ids.length });
        return;
      }

      if (action === 'publish') {
        await prisma.meetup.updateMany({
          where: { id: { in: ids } },
          data: { status: 'PUBLISHED' },
        });
        res.json({ success: true, affected: ids.length });
        return;
      }

      if (action === 'duplicate') {
        const originals = await prisma.meetup.findMany({ where: { id: { in: ids } } });
        const created = await Promise.all(
          originals.map((m) =>
            prisma.meetup.create({
              data: {
                title: incrementTitle(m.title),
                description: m.description,
                date: '',
                time: '',
                location: m.location,
                link: m.link || null,
                imageId: m.imageId || null,
                status: 'DRAFT',
                featured: false,
                visibility: 'PUBLIC',
              },
            })
          )
        );
        res.json(created);
        return;
      }

      res.status(400).json({ error: 'Unknown action' });
    } catch (err) {
      console.error('Bulk meetup error:', err);
      res.status(500).json({ error: 'Internal server error' });
    }
  }
);

router.post(
  '/:id/duplicate',
  requireAuth,
  requireRole(['ADMIN', 'MODERATOR']),
  async (req: Request, res: Response) => {
    try {
      const original = await prisma.meetup.findUnique({ where: { id: req.params.id as string } });
      if (!original) {
        res.status(404).json({ error: 'Meetup not found' });
        return;
      }

      const duplicate = await prisma.meetup.create({
        data: {
          title: incrementTitle(original.title),
          description: original.description,
          date: '',
          time: '',
          location: original.location,
          link: original.link || null,
          imageId: original.imageId || null,
          status: 'DRAFT',
          featured: false,
          visibility: 'PUBLIC',
        },
      });

      res.status(201).json(duplicate);
    } catch (err) {
      console.error('Duplicate meetup error:', err);
      res.status(500).json({ error: 'Internal server error' });
    }
  }
);

router.patch(
  '/:id',
  requireAuth,
  requireRole(['ADMIN', 'MODERATOR']),
  async (req: Request, res: Response) => {
    try {
      const meetup = await prisma.meetup.findUnique({
        where: { id: req.params.id as string },
      });
      if (!meetup) {
        res.status(404).json({ error: 'Meetup not found' });
        return;
      }

      const { title, description, date, time, location, link, status, featured, imageId, visibility } =
        req.body;

      const updateData: any = {};
      if (title !== undefined) updateData.title = title;
      if (description !== undefined) updateData.description = description;
      if (date !== undefined) updateData.date = date;
      if (time !== undefined) updateData.time = time;
      if (location !== undefined) updateData.location = location;
      if (link !== undefined) updateData.link = link;
      if (status !== undefined) updateData.status = status;
      if (featured !== undefined) updateData.featured = featured;
      if (imageId !== undefined) updateData.imageId = imageId;
      if (visibility !== undefined) updateData.visibility = visibility;

      const updated = await prisma.meetup.update({
        where: { id: req.params.id as string },
        data: updateData,
      });

      res.json(updated);
    } catch (err) {
      console.error('Update meetup error:', err);
      res.status(500).json({ error: 'Internal server error' });
    }
  }
);

router.delete(
  '/:id',
  requireAuth,
  requireRole(['ADMIN']),
  async (req: Request, res: Response) => {
    try {
      const meetup = await prisma.meetup.findUnique({
        where: { id: req.params.id as string },
      });
      if (!meetup) {
        res.status(404).json({ error: 'Meetup not found' });
        return;
      }

      await prisma.meetup.delete({ where: { id: req.params.id as string } });
      res.json({ success: true });
    } catch (err) {
      console.error('Delete meetup error:', err);
      res.status(500).json({ error: 'Internal server error' });
    }
  }
);

export default router;
