import { Router } from 'express';
import { authenticate } from '../../middleware/auth';
import { requireRoles } from '../../middleware/rbac';
import { Role, ErrorCode, TripStatus } from '@saferoute/constants';
import { prisma } from '../../config/database';
import { sendSuccess, sendError } from '../../utils/response';

export const reportRoutes = Router();

reportRoutes.get('/daily-trips', authenticate, requireRoles(Role.OWNER, Role.CTO, Role.OPERATIONS_MANAGER, Role.SCHOOL_PRINCIPAL, Role.SCHOOL_TRANSPORT_ADMIN), async (req, res) => {
  try {
    const date = req.query.date ? new Date(req.query.date as string) : new Date();
    const startOfDay = new Date(date); startOfDay.setHours(0, 0, 0, 0);
    const endOfDay = new Date(date); endOfDay.setHours(23, 59, 59, 999);
    const where: any = { tripDate: { gte: startOfDay, lte: endOfDay } };
    if (req.query.schoolId) where.schoolId = req.query.schoolId;

    const trips = await prisma.trip.findMany({
      where, include: { route: { select: { name: true } }, vehicle: { select: { vehicleNumber: true } }, driver: { include: { user: { select: { fullName: true } } } } },
    });

    const summary = { total: trips.length, completed: trips.filter(t => t.status === TripStatus.TRIP_COMPLETED).length, active: trips.filter(t => ![TripStatus.TRIP_COMPLETED, TripStatus.CANCELLED, TripStatus.NOT_STARTED].includes(t.status as TripStatus)).length, cancelled: trips.filter(t => t.status === TripStatus.CANCELLED).length };
    sendSuccess(res, { date: date.toISOString().split('T')[0], summary, trips });
  } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Failed to generate report.'); }
});

reportRoutes.get('/student-boarding', authenticate, requireRoles(Role.OWNER, Role.SCHOOL_PRINCIPAL, Role.SCHOOL_TRANSPORT_ADMIN), async (req, res) => {
  try {
    const date = req.query.date ? new Date(req.query.date as string) : new Date();
    const startOfDay = new Date(date); startOfDay.setHours(0, 0, 0, 0);
    const endOfDay = new Date(date); endOfDay.setHours(23, 59, 59, 999);
    const scans = await prisma.rfidScanLog.findMany({
      where: { scannedAt: { gte: startOfDay, lte: endOfDay }, scanType: { in: ['BOARDING', 'MANUAL_BOARDING'] } },
      include: { student: { select: { id: true, fullName: true, classGrade: true } } }, orderBy: { scannedAt: 'asc' },
    });
    sendSuccess(res, { date: date.toISOString().split('T')[0], totalBoarded: scans.length, scans });
  } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Failed to generate report.'); }
});

reportRoutes.get('/gps-uptime', authenticate, requireRoles(Role.OWNER, Role.CTO, Role.HARDWARE_TECHNICIAN), async (_req, res) => {
  try {
    const devices = await prisma.gpsDevice.findMany({ include: { vehicle: { select: { vehicleNumber: true, school: { select: { name: true } } } } } });
    const now = Date.now();
    const staleMs = 5 * 60 * 1000;
    const report = devices.map(d => ({
      deviceImei: d.deviceImei, status: d.status, vehicle: d.vehicle?.vehicleNumber, school: d.vehicle?.school?.name,
      isOnline: d.lastSeenAt ? (now - d.lastSeenAt.getTime()) < staleMs : false,
      lastSeenAt: d.lastSeenAt?.toISOString() || 'Never',
    }));
    const online = report.filter(r => r.isOnline).length;
    sendSuccess(res, { total: report.length, online, offline: report.length - online, devices: report });
  } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Failed to generate report.'); }
});

reportRoutes.get('/delays', authenticate, requireRoles(Role.OWNER, Role.OPERATIONS_MANAGER, Role.SCHOOL_PRINCIPAL), async (req, res) => {
  try {
    const from = req.query.from ? new Date(req.query.from as string) : new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
    const to = req.query.to ? new Date(req.query.to as string) : new Date();
    const events = await prisma.tripEvent.findMany({
      where: { eventType: { contains: 'DELAYED' }, createdAt: { gte: from, lte: to } },
      include: { trip: { select: { id: true, route: { select: { name: true } }, vehicle: { select: { vehicleNumber: true } } } } },
      orderBy: { createdAt: 'desc' },
    });
    sendSuccess(res, { from: from.toISOString(), to: to.toISOString(), totalDelays: events.length, events });
  } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Failed to generate report.'); }
});

reportRoutes.get('/missed-boarding', authenticate, requireRoles(Role.OWNER, Role.SCHOOL_PRINCIPAL, Role.SCHOOL_TRANSPORT_ADMIN), async (req, res) => {
  try { sendSuccess(res, { message: 'Missed boarding report — requires trip completion analysis', data: [] }); } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Report failed.'); }
});

reportRoutes.get('/school-arrival', authenticate, async (req, res) => {
  try { sendSuccess(res, { message: 'School arrival report — based on geofence events', data: [] }); } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Report failed.'); }
});

reportRoutes.get('/route-deviation', authenticate, async (req, res) => {
  try { sendSuccess(res, { message: 'Route deviation report', data: [] }); } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Report failed.'); }
});

reportRoutes.get('/overspeed', authenticate, async (req, res) => {
  try { sendSuccess(res, { message: 'Overspeed report', data: [] }); } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Report failed.'); }
});

reportRoutes.get('/monthly-safety', authenticate, async (req, res) => {
  try { sendSuccess(res, { message: 'Monthly safety report', data: [] }); } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Report failed.'); }
});

reportRoutes.get('/driver-performance', authenticate, async (req, res) => {
  try { sendSuccess(res, { message: 'Driver performance report', data: [] }); } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Report failed.'); }
});
