import { Router, Response } from 'express';
import { authenticate, AuthRequest } from '../middleware/auth';
import { requireRole } from '../middleware/requireRole';
import { validate } from '../middleware/validate';
import { CreateCustomerSchema, UpdateCustomerSchema } from '@nobel/shared';
import { generatePortalToken } from '../services/portal.service';
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 cursor = qstr(req, 'cursor');
  const take = Math.min(parseInt(qstrDef(req, 'limit', '50')) || 50, 100);

  const where = {
    deletedAt: null as null,
    ...(search ? {
      OR: [
        { name: { contains: search, mode: 'insensitive' as const } },
        { email: { contains: search, mode: 'insensitive' as const } },
        { phone: { contains: search } },
      ],
    } : {}),
  };

  const [customers, total] = await Promise.all([
    prisma.customer.findMany({
      where,
      take: take + 1,
      ...(cursor ? { cursor: { id: cursor }, skip: 1 } : {}),
      orderBy: { createdAt: 'desc' },
      include: { _count: { select: { orders: true, vehicles: true } } },
    }),
    prisma.customer.count({ where }),
  ]);

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

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

router.post('/', requireRole('admin', 'staff'), validate(CreateCustomerSchema), async (req: AuthRequest, res: Response) => {
  const customer = await prisma.customer.create({
    data: { ...req.body, portalToken: generatePortalToken() },
  });

  await prisma.auditLog.create({
    data: { userId: req.user!.sub, action: 'create_customer', entityType: 'Customer', entityId: customer.id },
  });

  res.status(201).json(customer);
});

router.get('/:id', async (req: AuthRequest, res: Response) => {
  const customer = await prisma.customer.findFirst({
    where: { id: req.params.id, deletedAt: null },
    include: {
      vehicles: { where: { deletedAt: null } },
      orders: {
        orderBy: { createdAt: 'desc' },
        take: 20,
        include: { vehicle: true, items: true, receipt: true },
      },
    },
  });
  if (!customer) { res.status(404).json({ error: 'Customer not found' }); return; }
  res.json(customer);
});

router.patch('/:id', requireRole('admin', 'staff'), validate(UpdateCustomerSchema), async (req: AuthRequest, res: Response) => {
  const customer = await prisma.customer.update({
    where: { id: req.params.id },
    data: req.body,
  });
  res.json(customer);
});

router.delete('/:id', requireRole('admin'), async (req: AuthRequest, res: Response) => {
  await prisma.customer.update({
    where: { id: req.params.id },
    data: { deletedAt: new Date() },
  });
  res.json({ ok: true });
});

router.get('/:id/orders', async (req: AuthRequest, res: Response) => {
  const orders = await prisma.workOrder.findMany({
    where: { customerId: req.params.id },
    orderBy: { createdAt: 'desc' },
    include: { vehicle: true, items: true, receipt: true },
  });
  res.json({ data: orders });
});

export default router;
