import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify'
import { getDatabase } from '../lib/db'
import { PDFExportDatabaseClient } from '../features/pdf-export/db-client'
import { PDFRenderer, renderTemplate } from '../features/pdf-export/renderer'
import { PDFCacheManager } from '../features/pdf-export/cache-manager'
import * as fs from 'fs/promises'
import * as path from 'path'
import type { PDFTemplateData } from '../features/pdf-export/types'

const db = new PDFExportDatabaseClient(getDatabase())
const renderer = new PDFRenderer()
const cache = new PDFCacheManager()

interface ExportPDFQuery {
  asn: string
  format?: string
}

async function loadTemplate(format: string): Promise<string> {
  const templatePath = path.join(
    __dirname,
    '../features/pdf-export/templates',
    `${format}-template.html`
  )

  try {
    return await fs.readFile(templatePath, 'utf-8')
  } catch (error) {
    throw new Error(`Template not found: ${format}`)
  }
}

async function getNetworkData(asn: number): Promise<PDFTemplateData> {
  const now = new Date()

  return {
    asn,
    network_name: `AS${asn} Network`,
    generated_at: now.toISOString(),
    health_score: {
      overall: 78,
      aspa: 65,
      rpki: 85,
      bgp_stability: 80,
      peering_health: 75,
    },
    aspa: {
      adoption_status: 'in_progress',
      provider_verification: 45,
      readiness_score: 60,
    },
    peering: {
      ixp_connections: 12,
      peer_count: 42,
      open_peers: 28,
      route_exports: 1250,
    },
    threats: {
      recent_hijacks: 0,
      anomalies_detected: 2,
      rpki_invalids: 3,
      moas_events: 1,
    },
    recommendations: [
      'Implement RPKI ROV for route validation',
      'Increase ASPA adoption to reduce path spoofing risk',
      'Review BGP community tagging practices',
      'Monitor anomalies for potential routing issues',
      'Expand IXP presence for redundancy',
    ],
    data_sources: [
      'RIPE RIS Route Collectors',
      'RouteViews BGP Archive',
      'RPKI Repository Objects',
      'PeeringDB Network Database',
      'WHOIS RDAP Queries',
    ],
  }
}

export async function pdfExportRoutes(fastify: FastifyInstance): Promise<void> {
  fastify.get<{ Querystring: ExportPDFQuery }>(
    '/export/pdf',
    async (request: FastifyRequest<{ Querystring: ExportPDFQuery }>, reply: FastifyReply) => {
      try {
        const asn = parseInt(request.query.asn, 10)
        const format = (request.query.format ?? 'report') as string

        if (isNaN(asn)) {
          return reply.status(400).send({ error: 'Invalid ASN' })
        }

        if (!['report', 'executive', 'technical'].includes(format)) {
          return reply.status(400).send({ error: 'Invalid format' })
        }

        const dateStr = new Date().toISOString().split('T')[0]
        const cacheKey = cache.generateKey(asn, format, dateStr)
        const cachedEntry = cache.get(cacheKey)

        if (cachedEntry) {
          console.log(`[PDF Export] Cache hit for AS${asn} format=${format}`)
          return reply
            .header('Content-Type', 'application/pdf')
            .header('Cache-Control', 'public, max-age=300')
            .header('X-Cache-Hit', 'true')
            .send(cachedEntry.pdfBuffer)
        }

        await renderer.initialize()

        const template = await loadTemplate(format)
        const data = await getNetworkData(asn)
        const html = renderTemplate(template, data)

        const pdfBuffer = await renderer.renderPDF(html, 30000)

        cache.set(cacheKey, pdfBuffer)

        await db.recordPDFGeneration(
          `AS${asn}`,
          format,
          require('crypto').createHash('sha256').update(pdfBuffer).digest('hex'),
          pdfBuffer.length,
          { format, generated_at: new Date().toISOString() }
        )

        return reply
          .header('Content-Type', 'application/pdf')
          .header('Cache-Control', 'public, max-age=300')
          .header('X-Cache-Hit', 'false')
          .send(pdfBuffer)
      } catch (error) {
        console.error('[PDF Export] Error generating PDF:', error)
        return reply.status(500).send({
          error: 'Failed to generate PDF',
          message: error instanceof Error ? error.message : 'Unknown error',
        })
      }
    }
  )

  fastify.get('/export/pdf/stats', async (request: FastifyRequest, reply: FastifyReply) => {
    try {
      const stats = await db.getPDFStats()
      const cacheStats = cache.getStats()

      return reply.send({
        database: stats,
        cache: cacheStats,
        ttl_ms: 5 * 60 * 1000,
      })
    } catch (error) {
      console.error('[PDF Export] Error fetching stats:', error)
      return reply.status(500).send({ error: 'Failed to fetch stats' })
    }
  })
}
