import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
import { reportService } from '@shieldai/report';
import { prisma } from '@shieldai/db';
import { ReportType, ReportStatus, ReportDataPayload } from '@shieldai/types';

interface AuthRequest extends FastifyRequest {
  user?: {
    id: string;
    email?: string;
    role?: string;
  };
}

export async function reportRoutes(fastify: FastifyInstance) {
  // Generate a new report
  fastify.post('/generate', async (request: FastifyRequest, reply: FastifyReply) => {
    const authReq = request as AuthRequest;
    const userId = authReq.user?.id;
    if (!userId) {
      return reply.code(401).send({ error: 'User ID required' });
    }

    const body = request.body as {
      reportType?: ReportType;
      periodStart?: string;
      periodEnd?: string;
    };

    const subscription = await prisma.subscription.findFirst({
      where: { userId, status: 'active' },
      select: { id: true, tier: true },
    });

    if (!subscription) {
      return reply.code(404).send({ error: 'Active subscription not found' });
    }

    const reportType = body.reportType || (subscription.tier === 'premium' ? 'ANNUAL_PREMIUM' : 'MONTHLY_PLUS');

    const periodStart = body.periodStart ? new Date(body.periodStart) : undefined;
    const periodEnd = body.periodEnd ? new Date(body.periodEnd) : undefined;

    const report = await reportService.generateReport({
      userId,
      subscriptionId: subscription.id,
      reportType,
      periodStart,
      periodEnd,
    });

    return reply.code(201).send(report);
  });

  // Get report history
  fastify.get('/', async (request: FastifyRequest, reply: FastifyReply) => {
    const authReq = request as AuthRequest;
    const userId = authReq.user?.id;
    if (!userId) {
      return reply.code(401).send({ error: 'User ID required' });
    }

    const query = request.query as Record<string, string>;
    const limit = parseInt(query.limit || '20', 10);
    const offset = parseInt(query.offset || '0', 10);

    const reports = await reportService.getReportHistory(userId, limit, offset);
    return reply.code(200).send({ reports, count: reports.length });
  });

  // Get specific report
  fastify.get('/:reportId', async (request: FastifyRequest, reply: FastifyReply) => {
    const authReq = request as AuthRequest;
    const userId = authReq.user?.id;
    if (!userId) {
      return reply.code(401).send({ error: 'User ID required' });
    }

    const reportId = (request.params as { reportId: string }).reportId;

    try {
      const report = await reportService.getReportById(userId, reportId);
      return reply.code(200).send(report);
    } catch (error) {
      return reply.code(404).send({ error: error instanceof Error ? error.message : 'Report not found' });
    }
  });

  // Get report HTML content
  fastify.get('/:reportId/html', async (request: FastifyRequest, reply: FastifyReply) => {
    const authReq = request as AuthRequest;
    const userId = authReq.user?.id;
    if (!userId) {
      return reply.code(401).send({ error: 'User ID required' });
    }

    const reportId = (request.params as { reportId: string }).reportId;

    const report = await prisma.securityReport.findFirst({
      where: { id: reportId, userId },
      select: { htmlContent: true, status: true },
    });

    if (!report) {
      return reply.code(404).send({ error: 'Report not found' });
    }

    if (report.status !== 'COMPLETED') {
      return reply.code(404).send({ error: 'Report not yet completed' });
    }

    reply.header('Content-Type', 'text/html');
    return reply.code(200).send(report.htmlContent || '');
  });

  // Get report PDF
  fastify.get('/:reportId/pdf', async (request: FastifyRequest, reply: FastifyReply) => {
    const authReq = request as AuthRequest;
    const userId = authReq.user?.id;
    if (!userId) {
      return reply.code(401).send({ error: 'User ID required' });
    }

    const reportId = (request.params as { reportId: string }).reportId;

    const report = await prisma.securityReport.findFirst({
      where: { id: reportId, userId },
      select: { dataPayload: true, title: true, status: true, htmlContent: true },
    });

    if (!report) {
      return reply.code(404).send({ error: 'Report not found' });
    }

    if (report.status !== 'COMPLETED') {
      return reply.code(404).send({ error: 'Report not yet completed' });
    }

    const { pdfGenerator } = await import('@shieldai/report');
    const pdfData = report.dataPayload
      ? (typeof report.dataPayload === 'string' ? JSON.parse(report.dataPayload) : report.dataPayload as unknown as ReportDataPayload)
      : {
        exposureSummary: { totalExposures: 0, newExposures: 0, resolvedExposures: 0, criticalExposures: 0, warningExposures: 0, infoExposures: 0, exposuresBySource: {} },
        spamStats: { callsBlocked: 0, textsBlocked: 0, callsFlagged: 0, textsFlagged: 0, falsePositives: 0, totalSpamEvents: 0 },
        voiceStats: { analysesRun: 0, threatsDetected: 0, enrollmentsActive: 0, syntheticDetections: 0, voiceMismatchEvents: 0 },
        recommendations: [],
        protectionScore: 0,
      };
    const pdfBuffer = await pdfGenerator.generate({
      reportTitle: report.title,
      periodStart: '',
      periodEnd: '',
      generatedAt: new Date().toISOString(),
      data: pdfData,
      reportId,
    });

    reply.header('Content-Type', 'application/pdf');
    reply.header('Content-Disposition', `inline; filename="${report.title}.pdf"`);
    return reply.code(200).send(pdfBuffer);
  });

  // Schedule pending reports (admin/scheduler endpoint)
  fastify.post('/schedule/monthly', async (request: FastifyRequest, reply: FastifyReply) => {
    const createdIds = await reportService.scheduleMonthlyReports();
    return reply.code(200).send({ scheduled: createdIds.length, reportIds: createdIds });
  });

  fastify.post('/schedule/annual', async (request: FastifyRequest, reply: FastifyReply) => {
    const createdIds = await reportService.scheduleAnnualReports();
    return reply.code(200).send({ scheduled: createdIds.length, reportIds: createdIds });
  });
}
