import { Router, Response } from 'express';
import { authenticate, AuthRequest } from '../middleware/auth';
import { requireRole } from '../middleware/requireRole';
import { qstr, qstrDef } from '../lib/query';
import prisma from '../lib/prisma';

const router = Router();
router.use(authenticate);

router.get('/', async (req: AuthRequest, res: Response) => {
  const search = qstr(req, 'search');
  const method = qstr(req, 'method');
  const status = qstr(req, 'status');
  const cursor = qstr(req, 'cursor');
  const take = Math.min(parseInt(qstrDef(req, 'limit', '50')) || 50, 100);

  const where: Record<string, unknown> = {};
  if (method) where.method = method;
  if (status) where.status = status;
  if (search) {
    where.OR = [
      { no: { contains: search, mode: 'insensitive' } },
      { order: { no: { contains: search, mode: 'insensitive' } } },
      { order: { customer: { name: { contains: search, mode: 'insensitive' } } } },
    ];
  }

  const [receipts, total] = await Promise.all([
    prisma.receipt.findMany({
      where,
      take: take + 1,
      ...(cursor ? { cursor: { id: cursor }, skip: 1 } : {}),
      orderBy: { date: 'desc' },
      include: {
        order: {
          include: {
            customer: { select: { id: true, name: true } },
            vehicle: { select: { id: true, year: true, make: true, model: true } },
            _count: { select: { items: true } },
          },
        },
      },
    }),
    prisma.receipt.count({ where }),
  ]);

  const hasMore = receipts.length > take;
  if (hasMore) receipts.pop();

  res.json({
    data: receipts,
    nextCursor: hasMore ? receipts[receipts.length - 1]?.id : null,
    total,
  });
});

router.get('/:id', async (req: AuthRequest, res: Response) => {
  const receipt = await prisma.receipt.findUnique({
    where: { id: req.params.id },
    include: {
      order: {
        include: {
          customer: true,
          vehicle: true,
          items: { include: { inventoryItem: { select: { id: true, sku: true } } } },
          assignedTo: { select: { id: true, name: true } },
        },
      },
    },
  });
  if (!receipt) { res.status(404).json({ error: 'Receipt not found' }); return; }
  res.json(receipt);
});

router.patch('/:id/refund', requireRole('admin', 'accounts'), async (req: AuthRequest, res: Response) => {
  const receipt = await prisma.$transaction(async (tx) => {
    const updated = await tx.receipt.updateMany({
      where: { id: req.params.id, status: 'paid' },
      data: { status: 'refunded' },
    });
    if (updated.count === 0) return null;

    await tx.auditLog.create({
      data: {
        userId: req.user!.sub,
        action: 'refund_receipt',
        entityType: 'Receipt',
        entityId: req.params.id,
      },
    });
    return tx.receipt.findUnique({ where: { id: req.params.id } });
  });

  if (!receipt) {
    res.status(409).json({ error: 'Receipt not found or already refunded' });
    return;
  }
  res.json(receipt);
});

export default router;
