/**
 * PDF Generation Routes
 * API endpoints for generating various types of PDFs
 */

import { FastifyInstance } from 'fastify'
import { z } from 'zod'
import { pdfService } from '../services/pdf.service'

// Validation schemas
const textPDFSchema = z.object({
  content: z.string().min(1),
  options: z.object({
    width: z.number().default(612),
    height: z.number().default(792),
    margin: z.number().default(72)
  }).optional()
})

const certificateSchema = z.object({
  title: z.string().min(1),
  recipientName: z.string().min(1),
  description: z.string().min(1),
  date: z.string(),
  certificateNumber: z.string().min(1),
  authorizedBy: z.string().optional()
})

const labelSchema = z.object({
  title: z.string().min(1),
  subtitle: z.string().optional(),
  qrCode: z.string().optional(),
  details: z.array(z.object({
    label: z.string(),
    value: z.string()
  })).optional().default([])
})

export async function pdfRoutes(fastify: FastifyInstance) {
  // Register a custom font for PDF generation
  fastify.post('/fonts/register', async (request, reply) => {
    try {
      const data = request.body as { name: string; fontData: string }; // base64 encoded font data

      if (!data.name || !data.fontData) {
        return reply.code(400).send({ error: 'Missing font name or data' });
      }

      // Convert base64 to Uint8Array
      const binaryString = Buffer.from(data.fontData, 'base64').toString('binary');
      const fontBytes = new Uint8Array(binaryString.length);
      for (let i = 0; i < binaryString.length; i++) {
        fontBytes[i] = binaryString.charCodeAt(i);
      }

      pdfService.registerFont(data.name, fontBytes);

      reply.send({
        success: true,
        font: data.name,
        message: `Font "${data.name}" registered successfully`
      });
    } catch (error: any) {
      reply.code(500).send({ error: 'Font registration failed', message: error?.message || 'Unknown error' });
    }
  });

  // List registered fonts
  fastify.get('/fonts', async (request, reply) => {
    try {
      const fonts = pdfService.getRegisteredFonts();
      reply.send({ fonts });
    } catch (error: any) {
      reply.code(500).send({ error: 'Failed to list fonts', message: error?.message || 'Unknown error' });
    }
  });

  // Generate a simple text PDF
  fastify.post('/text', async (request, reply) => {
    try {
      const body = textPDFSchema.parse(request.body)
      const pdf = pdfService.generateTextPDF(body.content, body.options || { width: 612, height: 792, margin: 72 })

      reply
        .type('application/pdf')
        .header('Content-Disposition', 'attachment; filename="document.pdf"')
        .send(pdf)
    } catch (error: any) {
      reply.code(400).send({ error: 'Invalid request', message: error?.message || 'Unknown error' })
    }
  })

  // Generate a certificate PDF
  fastify.post('/certificate', async (request, reply) => {
    try {
      const body = certificateSchema.parse(request.body)
      const pdf = pdfService.generateCertificate(body)

      reply
        .type('application/pdf')
        .header('Content-Disposition', `attachment; filename="certificate-${body.certificateNumber}.pdf"`)
        .send(pdf)
    } catch (error: any) {
      reply.code(400).send({ error: 'Invalid request', message: error?.message || 'Unknown error' })
    }
  })

  // Generate a label PDF
  fastify.post('/label', async (request, reply) => {
    try {
      const body = labelSchema.parse(request.body)
      const pdf = pdfService.generateLabel(body)

      reply
        .type('application/pdf')
        .header('Content-Disposition', 'attachment; filename="label.pdf"')
        .send(pdf)
    } catch (error: any) {
      reply.code(400).send({ error: 'Invalid request', message: error?.message || 'Unknown error' })
    }
  })

  // Health check for PDF service
  fastify.get('/health', async (request, reply) => {
    reply.send({
      status: 'ok',
      service: 'tinypdf-plus',
      timestamp: new Date().toISOString()
    })
  })
}
