// products.ts
import { Router, Request, Response } from 'express';
import { PrismaClient } from '@prisma/client';
const prismaProducts = new PrismaClient();
const productsRouter = Router();

productsRouter.get('/', async (req: Request, res: Response) => {
  try {
    const { category, tag } = req.query as any;
    const products = await prismaProducts.product.findMany({
      where: {
        published: true,
        ...(category && { category }),
        ...(tag && { tags: { has: tag } })
      },
      orderBy: [{ featured: 'desc' }, { clickCount: 'desc' }]
    });
    res.json({ products });
  } catch { res.status(500).json({ error: 'Failed to fetch products' }); }
});

productsRouter.post('/:id/click', async (req: Request, res: Response) => {
  try {
    await prismaProducts.product.update({ where: { id: req.params.id }, data: { clickCount: { increment: 1 } } });
    res.json({ ok: true });
  } catch { res.json({ ok: false }); }
});

export { productsRouter };

// blog.ts
import { Router as BlogRouter, Request as BlogReq, Response as BlogRes } from 'express';
const prismaBlog = new PrismaClient();
export const blogRouter = BlogRouter();

blogRouter.get('/', async (req: BlogReq, res: BlogRes) => {
  try {
    const { category, tag, page = '1' } = req.query as any;
    const take = 12;
    const skip = (parseInt(page) - 1) * take;
    const where: any = { published: true };
    if (category) where.category = { slug: category };
    if (tag) where.tags = { has: tag };

    const [posts, total] = await Promise.all([
      prismaBlog.blogPost.findMany({
        where,
        select: { id: true, slug: true, title: true, excerpt: true, imageUrl: true, publishedAt: true, readingTime: true, category: { select: { name: true, slug: true } }, tags: true },
        orderBy: [{ featured: 'desc' }, { publishedAt: 'desc' }],
        take, skip
      }),
      prismaBlog.blogPost.count({ where })
    ]);

    res.json({ posts, total, pages: Math.ceil(total / take) });
  } catch { res.status(500).json({ error: 'Failed to fetch posts' }); }
});

blogRouter.get('/:slug', async (req: BlogReq, res: BlogRes) => {
  try {
    const post = await prismaBlog.blogPost.findUnique({
      where: { slug: req.params.slug, published: true },
      include: { category: true }
    });
    if (!post) return res.status(404).json({ error: 'Post not found' });
    await prismaBlog.blogPost.update({ where: { id: post.id }, data: { viewCount: { increment: 1 } } });
    res.json({ post });
  } catch { res.status(500).json({ error: 'Failed to fetch post' }); }
});

// leads.ts
import { Router as LeadsRouter, Request as LeadsReq, Response as LeadsRes } from 'express';
import { z as LeadsZ } from 'zod';
const prismaLeads = new PrismaClient();
export const leadsRouter = LeadsRouter();

leadsRouter.post('/', async (req: LeadsReq, res: LeadsRes) => {
  try {
    const { email, name, source } = LeadsZ.object({
      email: LeadsZ.string().email(),
      name: LeadsZ.string().optional(),
      source: LeadsZ.string().optional()
    }).parse(req.body);

    await prismaLeads.emailLead.upsert({
      where: { email },
      create: { email, name, source: (source as any) || 'HOMEPAGE_HERO' },
      update: { name: name || undefined }
    });

    res.json({ success: true, message: 'Check your email for your free keto plan!' });
  } catch (err: any) {
    if (err instanceof LeadsZ.ZodError) return res.status(400).json({ error: 'Invalid email' });
    res.status(500).json({ error: 'Failed to subscribe' });
  }
});

// user.ts
import { Router as UserRouter, Response as UserRes } from 'express';
import { z as UserZ } from 'zod';
import { AuthRequest as UserAuthReq } from '../middleware/auth';
const prismaUser = new PrismaClient();
export const userRouter = UserRouter();

userRouter.get('/dashboard', async (req: UserAuthReq, res: UserRes) => {
  try {
    const [purchases, aiSessions, progressLogs, achievements, wishlist] = await Promise.all([
      prismaUser.purchase.findMany({ where: { userId: req.user!.id }, include: { plan: { select: { title: true, slug: true, imageUrl: true, duration: true } } }, orderBy: { createdAt: 'desc' } }),
      prismaUser.aiSession.findMany({ where: { userId: req.user!.id }, orderBy: { createdAt: 'desc' }, take: 5, select: { id: true, createdAt: true, inputParams: true } }),
      prismaUser.progressLog.findMany({ where: { userId: req.user!.id }, orderBy: { date: 'desc' }, take: 30 }),
      prismaUser.userAchievement.findMany({ where: { userId: req.user!.id }, include: { achievement: true }, orderBy: { earnedAt: 'desc' } }),
      prismaUser.wishlistItem.findMany({ where: { userId: req.user!.id }, include: { product: true } })
    ]);

    res.json({ purchases, aiSessions, progressLogs, achievements, wishlist });
  } catch { res.status(500).json({ error: 'Failed to fetch dashboard' }); }
});

userRouter.patch('/profile', async (req: UserAuthReq, res: UserRes) => {
  try {
    const body = UserZ.object({
      name: UserZ.string().min(2).max(50).optional(),
      weightKg: UserZ.number().optional(),
      targetWeightKg: UserZ.number().optional(),
      heightCm: UserZ.number().optional(),
      allergies: UserZ.array(UserZ.string()).optional(),
      ketoGoal: UserZ.string().optional()
    }).parse(req.body);

    const user = await prismaUser.user.update({ where: { id: req.user!.id }, data: body });
    res.json({ user: { id: user.id, name: user.name, email: user.email, role: user.role } });
  } catch { res.status(500).json({ error: 'Failed to update profile' }); }
});

userRouter.post('/wishlist/:productId', async (req: UserAuthReq, res: UserRes) => {
  try {
    const existing = await prismaUser.wishlistItem.findUnique({ where: { userId_productId: { userId: req.user!.id, productId: req.params.productId } } });
    if (existing) {
      await prismaUser.wishlistItem.delete({ where: { id: existing.id } });
      res.json({ saved: false });
    } else {
      await prismaUser.wishlistItem.create({ data: { userId: req.user!.id, productId: req.params.productId } });
      res.json({ saved: true });
    }
  } catch { res.status(500).json({ error: 'Failed to update wishlist' }); }
});

// admin.ts
import { Router as AdminRouter, Response as AdminRes } from 'express';
import { requireAdmin as AdminRequire } from '../middleware/auth';
import { AuthRequest as AdminAuthReq } from '../middleware/auth';
const prismaAdmin = new PrismaClient();
export const adminRouter = AdminRouter();

adminRouter.use(AdminRequire);

adminRouter.get('/stats', async (_req: AdminAuthReq, res: AdminRes) => {
  try {
    const [users, orders, leads, subscriptions] = await Promise.all([
      prismaAdmin.user.count(),
      prismaAdmin.order.aggregate({ _sum: { amount: true }, _count: true, where: { status: 'COMPLETED' } }),
      prismaAdmin.emailLead.count(),
      prismaAdmin.user.count({ where: { subscriptionStatus: 'ACTIVE' } })
    ]);
    res.json({ users, totalRevenue: orders._sum.amount || 0, totalOrders: orders._count, leads, activeSubscriptions: subscriptions });
  } catch { res.status(500).json({ error: 'Failed to fetch stats' }); }
});

adminRouter.get('/users', async (req: AdminAuthReq, res: AdminRes) => {
  try {
    const users = await prismaAdmin.user.findMany({ select: { id: true, email: true, name: true, role: true, subscriptionTier: true, subscriptionStatus: true, createdAt: true, streakCount: true }, orderBy: { createdAt: 'desc' }, take: 100 });
    res.json({ users });
  } catch { res.status(500).json({ error: 'Failed to fetch users' }); }
});

adminRouter.get('/orders', async (_req: AdminAuthReq, res: AdminRes) => {
  try {
    const orders = await prismaAdmin.order.findMany({ include: { user: { select: { email: true, name: true } }, purchases: { include: { plan: { select: { title: true } } } } }, orderBy: { createdAt: 'desc' }, take: 50 });
    res.json({ orders });
  } catch { res.status(500).json({ error: 'Failed to fetch orders' }); }
});

adminRouter.get('/leads', async (_req: AdminAuthReq, res: AdminRes) => {
  try {
    const leads = await prismaAdmin.emailLead.findMany({ orderBy: { createdAt: 'desc' } });
    res.json({ leads });
  } catch { res.status(500).json({ error: 'Failed to fetch leads' }); }
});
