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

export const parentAppRoutes = Router();

parentAppRoutes.get('/children', authenticate, requireRoles(Role.PARENT, Role.GUARDIAN), async (req, res) => {
  try {
    const parents = await prisma.parent.findMany({
      where: { userId: req.user!.userId },
      include: {
        student: {
          select: { id: true, fullName: true, classGrade: true, section: true, photoUrl: true, isActive: true,
            school: { select: { id: true, name: true } },
            rfidCards: { where: { status: 'ACTIVE' }, select: { cardUid: true } },
            routeStudents: { include: { route: { select: { id: true, name: true, type: true, vehicle: { select: { id: true, vehicleNumber: true } } } } } },
          },
        },
      },
    });
    sendSuccess(res, parents.map(p => ({ ...p.student, relationship: p.relationship, isPrimary: p.isPrimary })));
  } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Failed.'); }
});

parentAppRoutes.get('/children/:studentId/live', authenticate, requireRoles(Role.PARENT, Role.GUARDIAN), async (req, res) => {
  try {

    const isParent = await prisma.parent.findFirst({ where: { userId: req.user!.userId, studentId: req.params.studentId } });
    if (!isParent) { sendError(res, ErrorCode.ACCESS_DENIED, 'This is not your child.', {}, 403); return; }

    const routeStudents = await prisma.routeStudent.findMany({ where: { studentId: req.params.studentId } });
    const routeIds = routeStudents.map(rs => rs.routeId);

    const activeTrip = await prisma.trip.findFirst({
      where: { routeId: { in: routeIds }, status: { notIn: ['TRIP_COMPLETED', 'CANCELLED', 'NOT_STARTED'] } },
      include: {
        route: { select: { name: true } },
        vehicle: { select: { id: true, vehicleNumber: true, vehicleType: true } },
        driver: { include: { user: { select: { fullName: true, phone: true } } } },
      },
      orderBy: { createdAt: 'desc' },
    });

    if (!activeTrip) { sendSuccess(res, { hasActiveTrip: false }, 'No active trip'); return; }

    const latestLocation = await prisma.gpsLocationLog.findFirst({
      where: { vehicleId: activeTrip.vehicleId }, orderBy: { recordedAt: 'desc' },
    });

    const isStale = latestLocation ? (Date.now() - latestLocation.recordedAt.getTime()) > config.gps.staleThresholdMinutes * 60 * 1000 : true;

    const boardingScan = await prisma.rfidScanLog.findFirst({
      where: { studentId: req.params.studentId, tripId: activeTrip.id, scanType: { in: ['BOARDING', 'MANUAL_BOARDING'] } },
    });

    sendSuccess(res, {
      hasActiveTrip: true,
      trip: {
        id: activeTrip.id, status: activeTrip.status, type: activeTrip.type,
        route: activeTrip.route.name, vehicle: activeTrip.vehicle,
        driver: { name: activeTrip.driver.user.fullName, phone: '****' + activeTrip.driver.user.phone.slice(-4) }, // Masked per Blueprint Rule 19
        startedAt: activeTrip.startedAt?.toISOString(),
      },
      location: latestLocation ? {
        latitude: latestLocation.latitude, longitude: latestLocation.longitude,
        speed: latestLocation.speed, recordedAt: latestLocation.recordedAt.toISOString(),
        lastUpdatedAt: latestLocation.receivedAt.toISOString(),
        isStale, ...(isStale && { warning: 'Location may be outdated' }),
      } : null,
      boarding: boardingScan ? { boarded: true, scannedAt: boardingScan.scannedAt.toISOString() } : { boarded: false },
    });
  } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Failed.'); }
});

parentAppRoutes.get('/children/:studentId/trips', authenticate, requireRoles(Role.PARENT, Role.GUARDIAN), async (req, res) => {
  try {
    const isParent = await prisma.parent.findFirst({ where: { userId: req.user!.userId, studentId: req.params.studentId } });
    if (!isParent) { sendError(res, ErrorCode.ACCESS_DENIED, 'Not your child.', {}, 403); return; }

    const routeStudents = await prisma.routeStudent.findMany({ where: { studentId: req.params.studentId } });
    const routeIds = routeStudents.map(rs => rs.routeId);

    const trips = await prisma.trip.findMany({
      where: { routeId: { in: routeIds } }, orderBy: { tripDate: 'desc' }, take: 30,
      select: { id: true, tripDate: true, type: true, status: true, startedAt: true, endedAt: true },
    });
    sendSuccess(res, trips);
  } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Failed.'); }
});

parentAppRoutes.get('/notifications', authenticate, requireRoles(Role.PARENT, Role.GUARDIAN), async (req, res) => {
  try {
    const notifications = await prisma.notification.findMany({
      where: { userId: req.user!.userId }, orderBy: { createdAt: 'desc' }, take: 50,
    });
    sendSuccess(res, notifications);
  } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Failed.'); }
});

parentAppRoutes.get('/children/:studentId/welcome-kit', authenticate, requireRoles(Role.PARENT), async (req, res) => {
  try {
    const isParent = await prisma.parent.findFirst({ where: { userId: req.user!.userId, studentId: req.params.studentId } });
    if (!isParent) { sendError(res, ErrorCode.ACCESS_DENIED, 'Not your child.', {}, 403); return; }
    const kit = await prisma.welcomeKit.findFirst({
      where: { studentId: req.params.studentId }, include: { items: true }, orderBy: { createdAt: 'desc' },
    });
    if (!kit) { sendError(res, ErrorCode.WELCOME_KIT_NOT_ASSIGNED, 'No kit assigned.'); return; }
    sendSuccess(res, kit);
  } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Failed.'); }
});

parentAppRoutes.get('/children/:studentId/insurance', authenticate, requireRoles(Role.PARENT), async (req, res) => {
  try {
    const isParent = await prisma.parent.findFirst({ where: { userId: req.user!.userId, studentId: req.params.studentId } });
    if (!isParent) { sendError(res, ErrorCode.ACCESS_DENIED, 'Not your child.', {}, 403); return; }
    const requests = await prisma.insuranceRequest.findMany({
      where: { studentId: req.params.studentId, parentId: isParent.id },
      include: { partner: { select: { name: true } } },
    });
    sendSuccess(res, requests);
  } catch (error) { sendError(res, ErrorCode.SERVER_ERROR, 'Failed.'); }
});
