import { Router, Request, Response, NextFunction } from 'express';
import { campaignsService } from './campaigns.service';
import { prisma } from '../../../config/database';
import { redis } from '../../../config/redis';

const router = Router();

// GET /api/campaigns/public?page=1&limit=20 — list active campaigns (public, paginated)
router.get(
  '/public',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const page = Math.max(parseInt(req.query.page as string) || 1, 1);
      const limit = Math.min(parseInt(req.query.limit as string) || 20, 50);
      const result = await campaignsService.findActiveCampaigns(page, limit);
      res.json(result);
    } catch (err) {
      next(err);
    }
  }
);

// GET /api/campaigns/:slug/details — public campaign data (ACTIVE only)
router.get(
  '/:slug/details',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const slug = req.params.slug as string;
      const campaign = await campaignsService.findBySlugPublic(slug);
      res.json(campaign);
    } catch (err) {
      next(err);
    }
  }
);

// GET /api/campaigns/:slug/related — related campaigns + upcoming shifts
router.get(
  '/:slug/related',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const slug = req.params.slug as string;
      const cacheKey = `campaign:related:${slug}`;

      // Check cache
      try {
        const cached = await redis.get(cacheKey);
        if (cached) { res.json(JSON.parse(cached)); return; }
      } catch { /* cache miss */ }

      // Find current campaign
      const campaign = await prisma.campaign.findFirst({
        where: { slug, status: 'ACTIVE' },
        select: { id: true, targetGovernmentLevels: true },
      });

      if (!campaign) {
        res.json({ campaigns: [], shifts: [] });
        return;
      }

      // Related campaigns: same gov levels, exclude current, limit 3
      const relatedCampaigns = await prisma.campaign.findMany({
        where: {
          status: 'ACTIVE',
          id: { not: campaign.id },
          ...(campaign.targetGovernmentLevels.length > 0 && {
            targetGovernmentLevels: { hasSome: campaign.targetGovernmentLevels },
          }),
        },
        select: {
          id: true,
          slug: true,
          title: true,
          description: true,
          _count: { select: { emails: true } },
        },
        orderBy: { createdAt: 'desc' },
        take: 3,
      });

      // Related shifts: upcoming, limit 3
      const today = new Date();
      today.setHours(0, 0, 0, 0);

      const relatedShifts = await prisma.shift.findMany({
        where: {
          date: { gte: today },
          status: 'OPEN',
        },
        select: {
          id: true,
          title: true,
          date: true,
          startTime: true,
          location: true,
          maxVolunteers: true,
          _count: { select: { signups: true } },
        },
        orderBy: { date: 'asc' },
        take: 3,
      });

      const result = {
        campaigns: relatedCampaigns.map(c => ({
          id: c.id,
          slug: c.slug,
          title: c.title,
          description: c.description?.slice(0, 150) ?? null,
          emailCount: c._count.emails,
        })),
        shifts: relatedShifts.map(s => ({
          id: s.id,
          title: s.title,
          startTime: `${s.date.toISOString().split('T')[0]}T${s.startTime}:00`,
          location: s.location,
          currentVolunteers: s._count.signups,
          maxVolunteers: s.maxVolunteers,
        })),
      };

      try { await redis.setex(cacheKey, 300, JSON.stringify(result)); } catch { /* non-critical */ }

      res.json(result);
    } catch (err) {
      next(err);
    }
  }
);

export { router as campaignPublicRouter };
