import { Router } from 'express';
import { prisma } from '../../config/database.js';
import { requireModerator, requireAdmin } from '../../middleware/requireRole.js';
import { validate } from '../../middleware/validate.js';
import { rejectListingSchema } from '../../validators/admin.js';
import { AppError } from '../../middleware/errorHandler.js';

const router = Router();

// GET /api/admin/listings - All listings
router.get('/', requireModerator, async (req, res, next) => {
  try {
    const { page = '1', pageSize = '20', status, category, search } = req.query;
    const skip = (parseInt(page as string) - 1) * parseInt(pageSize as string);
    const take = parseInt(pageSize as string);

    const where: any = {};
    if (status) where.status = status;
    if (category) where.category = category;
    if (search) {
      where.OR = [
        { title: { contains: search as string, mode: 'insensitive' } },
        { description: { contains: search as string, mode: 'insensitive' } },
      ];
    }

    const [listings, total] = await Promise.all([
      prisma.listing.findMany({
        where,
        select: {
          id: true, title: true, price: true, category: true, condition: true,
          status: true, isFeatured: true, createdAt: true, viewCount: true,
          seller: { select: { id: true, fullName: true, avatar: true } },
          images: { take: 1, orderBy: { order: 'asc' } },
          _count: { select: { offers: true, favorites: true } },
        },
        skip,
        take,
        orderBy: { createdAt: 'desc' },
      }),
      prisma.listing.count({ where }),
    ]);

    res.json({
      data: listings,
      total,
      page: parseInt(page as string),
      pageSize: take,
      totalPages: Math.ceil(total / take),
    });
  } catch (error) {
    next(error);
  }
});

// POST /api/admin/listings/:id/approve
router.post('/:id/approve', requireModerator, async (req, res, next) => {
  try {
    const listing = await prisma.listing.findUnique({ where: { id: req.params.id } });
    if (!listing) throw new AppError(404, 'Listing not found');
    if (listing.status !== 'PENDING_REVIEW') throw new AppError(400, 'Listing is not pending review');

    const updated = await prisma.listing.update({
      where: { id: req.params.id },
      data: { status: 'ACTIVE', reviewedBy: req.userId, reviewedAt: new Date() },
    });

    await prisma.moderationLog.create({
      data: {
        moderatorId: req.userId!,
        targetListingId: req.params.id,
        action: 'APPROVED',
        reason: 'Listing approved',
      },
    });

    await prisma.notification.create({
      data: {
        userId: listing.sellerId,
        type: 'LISTING_APPROVED',
        title: 'Listing Approved',
        body: `Your listing "${listing.title}" has been approved and is now live.`,
        data: { listingId: listing.id },
      },
    });

    res.json(updated);
  } catch (error) {
    next(error);
  }
});

// POST /api/admin/listings/:id/reject
router.post('/:id/reject', requireModerator, validate(rejectListingSchema), async (req, res, next) => {
  try {
    const listing = await prisma.listing.findUnique({ where: { id: req.params.id } });
    if (!listing) throw new AppError(404, 'Listing not found');

    const updated = await prisma.listing.update({
      where: { id: req.params.id },
      data: {
        status: 'DELETED',
        rejectionReason: req.body.reason,
        reviewedBy: req.userId,
        reviewedAt: new Date(),
      },
    });

    await prisma.moderationLog.create({
      data: {
        moderatorId: req.userId!,
        targetListingId: req.params.id,
        action: 'REJECTED',
        reason: req.body.reason,
      },
    });

    await prisma.notification.create({
      data: {
        userId: listing.sellerId,
        type: 'LISTING_REJECTED',
        title: 'Listing Rejected',
        body: `Your listing "${listing.title}" was rejected. Reason: ${req.body.reason}`,
        data: { listingId: listing.id },
      },
    });

    res.json(updated);
  } catch (error) {
    next(error);
  }
});

// DELETE /api/admin/listings/:id - Force delete
router.delete('/:id', requireAdmin, async (req, res, next) => {
  try {
    const listing = await prisma.listing.findUnique({ where: { id: req.params.id } });
    if (!listing) throw new AppError(404, 'Listing not found');

    await prisma.listing.update({
      where: { id: req.params.id },
      data: { status: 'DELETED' },
    });

    await prisma.moderationLog.create({
      data: {
        moderatorId: req.userId!,
        targetListingId: req.params.id,
        targetUserId: listing.sellerId,
        action: 'LISTING_DELETED',
        reason: 'Force deleted by admin',
      },
    });

    res.json({ message: 'Listing deleted' });
  } catch (error) {
    next(error);
  }
});

// POST /api/admin/listings/:id/feature - Toggle featured
router.post('/:id/feature', requireAdmin, async (req, res, next) => {
  try {
    const listing = await prisma.listing.findUnique({ where: { id: req.params.id } });
    if (!listing) throw new AppError(404, 'Listing not found');

    const updated = await prisma.listing.update({
      where: { id: req.params.id },
      data: { isFeatured: !listing.isFeatured },
    });

    await prisma.moderationLog.create({
      data: {
        moderatorId: req.userId!,
        targetListingId: req.params.id,
        action: 'LISTING_FEATURED',
        reason: updated.isFeatured ? 'Listing featured' : 'Listing unfeatured',
      },
    });

    res.json(updated);
  } catch (error) {
    next(error);
  }
});

export default router;
