// plans.ts
import { Router, Request, Response } from 'express';
import { PrismaClient } from '@prisma/client';
import { authenticate, requireAdmin, AuthRequest } from '../middleware/auth';
import { z } from 'zod';

const router = Router();
const prisma = new PrismaClient();

// GET /api/plans - public list
router.get('/', async (req: Request, res: Response) => {
  try {
    const plans = await prisma.ketoPlan.findMany({
      where: { published: true },
      select: {
        id: true, slug: true, title: true, shortDesc: true,
        duration: true, price: true, tier: true, featured: true,
        imageUrl: true, purchaseCount: true, avgRating: true, reviewCount: true
      },
      orderBy: [{ featured: 'desc' }, { purchaseCount: 'desc' }]
    });
    res.json({ plans });
  } catch { res.status(500).json({ error: 'Failed to fetch plans' }); }
});

// GET /api/plans/:slug - single plan (preview only if not purchased)
router.get('/:slug', async (req: Request, res: Response) => {
  try {
    const plan = await prisma.ketoPlan.findUnique({
      where: { slug: req.params.slug, published: true },
      include: { reviews: { where: { approved: true }, include: { user: { select: { name: true, avatarUrl: true } } }, take: 10 } }
    });
    if (!plan) return res.status(404).json({ error: 'Plan not found' });

    // Check purchase / subscription for full content
    let hasAccess = false;
    const token = req.headers.authorization?.split(' ')[1];
    if (token) {
      try {
        const jwt = await import('jsonwebtoken');
        const payload = jwt.default.verify(token, process.env.JWT_SECRET!) as any;
        const user = await prisma.user.findUnique({ where: { id: payload.sub }, select: { subscriptionTier: true, subscriptionStatus: true } });
        const purchased = await prisma.purchase.findUnique({ where: { userId_planId: { userId: payload.sub, planId: plan.id } } });
        hasAccess = !!purchased || ['PRO', 'LIFETIME', 'BASIC'].includes(user?.subscriptionTier || '') && user?.subscriptionStatus === 'ACTIVE';
      } catch {}
    }

    const response = hasAccess
      ? plan
      : { ...plan, meals: null, recipes: null, shoppingList: null, nutritionInfo: null, pdfUrl: null };

    res.json({ plan: response, hasAccess });
  } catch { res.status(500).json({ error: 'Failed to fetch plan' }); }
});

// POST /api/plans/:id/review - add review (must have purchased)
router.post('/:id/review', authenticate, async (req: AuthRequest, res: Response) => {
  try {
    const { rating, title, body } = z.object({ rating: z.number().min(1).max(5), title: z.string().max(100).optional(), body: z.string().max(1000).optional() }).parse(req.body);
    const purchased = await prisma.purchase.findUnique({ where: { userId_planId: { userId: req.user!.id, planId: req.params.id } } });
    if (!purchased) return res.status(403).json({ error: 'Must purchase plan to review' });

    const review = await prisma.review.upsert({
      where: { userId_planId: { userId: req.user!.id, planId: req.params.id } },
      create: { userId: req.user!.id, planId: req.params.id, rating, title, body },
      update: { rating, title, body }
    });

    // Update plan avg rating
    const reviews = await prisma.review.aggregate({ where: { planId: req.params.id, approved: true }, _avg: { rating: true }, _count: true });
    await prisma.ketoPlan.update({ where: { id: req.params.id }, data: { avgRating: reviews._avg.rating || 0, reviewCount: reviews._count } });

    res.json({ review });
  } catch (err: any) {
    if (err instanceof z.ZodError) return res.status(400).json({ error: 'Validation error' });
    res.status(500).json({ error: 'Failed to save review' });
  }
});

export { router as plansRouter };
