import prisma from '../services/prisma.js';
import asyncHandler from '../utils/asyncHandler.js';
import ApiError from '../utils/ApiError.js';
import { courseSchema } from '../utils/validators.js';
import slugify from '../utils/slug.js';

export const listCourses = asyncHandler(async (req, res) => {
  const where = { published: true };
  if (req.query.vendor) {
    const vendor = await prisma.vendor.findUnique({ where: { slug: req.query.vendor } });
    if (vendor) where.vendorId = vendor.id;
  }
  const courses = await prisma.course.findMany({
    where,
    orderBy: { title: 'asc' },
    include: {
      vendor: { select: { name: true, slug: true } },
      _count: { select: { questions: { where: { status: 'APPROVED' } } } },
    },
  });
  res.json({ success: true, courses });
});

// Public course detail (no answers). Includes whether current user has access.
export const getCourse = asyncHandler(async (req, res) => {
  const course = await prisma.course.findUnique({
    where: { slug: req.params.slug },
    include: {
      vendor: { select: { name: true, slug: true } },
      _count: { select: { questions: { where: { status: 'APPROVED' } } } },
    },
  });
  if (!course) throw ApiError.notFound('Course not found');

  let hasAccess = course.isFree || course.priceCents === 0;
  if (!hasAccess && req.user) {
    if (req.user.role === 'ADMIN') {
      hasAccess = true;
    } else {
      const purchase = await prisma.purchase.findFirst({
        where: { userId: req.user.id, courseId: course.id, status: 'PAID' },
      });
      hasAccess = Boolean(purchase);
    }
  }

  res.json({
    success: true,
    course: {
      ...course,
      totalQuestions: course._count.questions,
      hasAccess,
    },
  });
});

// ---- Admin ----
export const createCourse = asyncHandler(async (req, res) => {
  const data = courseSchema.parse(req.body);
  const vendor = await prisma.vendor.findUnique({ where: { id: data.vendorId } });
  if (!vendor) throw ApiError.badRequest('Vendor not found');

  const course = await prisma.course.create({
    data: {
      vendorId: data.vendorId,
      title: data.title,
      slug: slugify(`${vendor.slug}-${data.title}`),
      code: data.code || null,
      description: data.description || null,
      priceCents: data.priceCents,
      currency: data.currency,
      isFree: data.isFree,
      published: data.published,
      freeQuestionLimit: data.freeQuestionLimit,
      examMinutes: data.examMinutes,
    },
  });
  res.status(201).json({ success: true, course });
});

export const updateCourse = asyncHandler(async (req, res) => {
  const data = courseSchema.partial().parse(req.body);
  const course = await prisma.course.update({ where: { id: req.params.id }, data });
  res.json({ success: true, course });
});

export const deleteCourse = asyncHandler(async (req, res) => {
  await prisma.course.delete({ where: { id: req.params.id } });
  res.json({ success: true, message: 'Course deleted' });
});

// Admin listing including unpublished + counts
export const adminListCourses = asyncHandler(async (_req, res) => {
  const courses = await prisma.course.findMany({
    orderBy: { createdAt: 'desc' },
    include: {
      vendor: { select: { name: true, slug: true } },
      _count: { select: { questions: true } },
    },
  });
  res.json({ success: true, courses });
});
