/**
 * Export Routes for Redirect Intelligence v2
 * 
 * Provides endpoints for generating Markdown and PDF reports
 */

import express from 'express';
import { z } from 'zod';
import rateLimit from 'express-rate-limit';
import { ExportService } from '../services/export.service';
import { optionalAuth, requireAuth, AuthenticatedRequest } from '../middleware/auth.middleware';
import { logger } from '../lib/logger';

const router = express.Router();
const exportService = new ExportService();

// Rate limiting for export endpoints (more restrictive due to resource usage)
const exportLimiter = rateLimit({
  windowMs: 60 * 60 * 1000, // 1 hour
  max: 20, // Lower limit for resource-intensive exports
  message: {
    success: false,
    error: 'Export rate limit exceeded',
    message: 'Too many export requests. Please try again later.'
  },
  standardHeaders: true,
  legacyHeaders: false,
  keyGenerator: (req: AuthenticatedRequest) => {
    return req.user ? `user:${req.user.id}` : `ip:${req.ip}`;
  },
});

// Input validation schemas
const exportParamsSchema = z.object({
  checkId: z.string().min(1, 'Check ID is required'),
});

const exportQuerySchema = z.object({
  download: z.string().optional(),
  filename: z.string().optional(),
});

/**
 * GET /api/v2/export/:checkId/markdown
 * Generate and return Markdown report
 */
router.get('/:checkId/markdown', 
  optionalAuth, 
  exportLimiter, 
  async (req: AuthenticatedRequest, res) => {
    try {
      const { checkId } = exportParamsSchema.parse(req.params);
      const { download, filename } = exportQuerySchema.parse(req.query);
      
      logger.info(`Generating Markdown export for check: ${checkId}`, {
        userId: req.user?.id,
        download: !!download,
      });
      
      const markdown = await exportService.generateMarkdownReport(checkId, req.user?.id);
      
      // Set appropriate headers
      const fileName = filename || `redirect-report-${checkId}.md`;
      
      if (download) {
        res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`);
      }
      
      res.setHeader('Content-Type', 'text/markdown; charset=utf-8');
      res.setHeader('Content-Length', Buffer.byteLength(markdown, 'utf8'));
      
      res.send(markdown);
      
      logger.info(`Markdown export completed for check: ${checkId}`, {
        userId: req.user?.id,
        size: Buffer.byteLength(markdown, 'utf8'),
      });
      
    } catch (error) {
      logger.error('Markdown export failed:', error);
      
      if (error instanceof z.ZodError) {
        return res.status(400).json({
          success: false,
          error: 'Validation error',
          message: error.errors[0]?.message || 'Invalid input',
          details: error.errors
        });
      }
      
      const statusCode = error instanceof Error && error.message.includes('not found') ? 404 : 500;
      
      res.status(statusCode).json({
        success: false,
        error: 'Export failed',
        message: error instanceof Error ? error.message : 'Failed to generate markdown report'
      });
    }
  }
);

/**
 * GET /api/v2/export/:checkId/pdf
 * Generate and return PDF report
 */
router.get('/:checkId/pdf', 
  optionalAuth, 
  exportLimiter, 
  async (req: AuthenticatedRequest, res) => {
    try {
      const { checkId } = exportParamsSchema.parse(req.params);
      const { download, filename } = exportQuerySchema.parse(req.query);
      
      logger.info(`Generating PDF export for check: ${checkId}`, {
        userId: req.user?.id,
        download: !!download,
      });
      
      const pdfBuffer = await exportService.generatePdfReport(checkId, req.user?.id);
      
      // Set appropriate headers
      const fileName = filename || `redirect-report-${checkId}.pdf`;
      
      res.setHeader('Content-Type', 'application/pdf');
      res.setHeader('Content-Length', pdfBuffer.length);
      
      if (download) {
        res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`);
      } else {
        res.setHeader('Content-Disposition', `inline; filename="${fileName}"`);
      }
      
      // Security headers for PDF
      res.setHeader('X-Content-Type-Options', 'nosniff');
      res.setHeader('X-Frame-Options', 'SAMEORIGIN');
      
      res.send(pdfBuffer);
      
      logger.info(`PDF export completed for check: ${checkId}`, {
        userId: req.user?.id,
        size: pdfBuffer.length,
      });
      
    } catch (error) {
      logger.error('PDF export failed:', error);
      
      if (error instanceof z.ZodError) {
        return res.status(400).json({
          success: false,
          error: 'Validation error',
          message: error.errors[0]?.message || 'Invalid input',
          details: error.errors
        });
      }
      
      const statusCode = error instanceof Error && error.message.includes('not found') ? 404 : 500;
      
      res.status(statusCode).json({
        success: false,
        error: 'Export failed',
        message: error instanceof Error ? error.message : 'Failed to generate PDF report'
      });
    }
  }
);

/**
 * POST /api/v2/export/:checkId/save
 * Generate and save report to file system (for authenticated users)
 */
router.post('/:checkId/save', 
  requireAuth, 
  exportLimiter, 
  async (req: AuthenticatedRequest, res) => {
    try {
      const { checkId } = exportParamsSchema.parse(req.params);
      const { format = 'both' } = z.object({
        format: z.enum(['markdown', 'pdf', 'both']).default('both'),
      }).parse(req.body);
      
      logger.info(`Saving reports for check: ${checkId}`, {
        userId: req.user!.id,
        format,
      });
      
      const results: { format: string; path: string }[] = [];
      
      // Generate and save Markdown if requested
      if (format === 'markdown' || format === 'both') {
        const markdown = await exportService.generateMarkdownReport(checkId, req.user!.id);
        const mdPath = await exportService.saveReport(markdown, checkId, 'md');
        results.push({ format: 'markdown', path: mdPath });
      }
      
      // Generate and save PDF if requested
      if (format === 'pdf' || format === 'both') {
        const pdfBuffer = await exportService.generatePdfReport(checkId, req.user!.id);
        const pdfPath = await exportService.saveReport(pdfBuffer, checkId, 'pdf');
        results.push({ format: 'pdf', path: pdfPath });
      }
      
      logger.info(`Reports saved for check: ${checkId}`, {
        userId: req.user!.id,
        results: results.length,
      });
      
      res.json({
        success: true,
        status: 200,
        data: {
          checkId,
          reports: results,
          savedAt: new Date().toISOString(),
        },
        meta: {
          version: 'v2',
          feature: 'export-save',
        }
      });
      
    } catch (error) {
      logger.error('Report save failed:', error);
      
      if (error instanceof z.ZodError) {
        return res.status(400).json({
          success: false,
          error: 'Validation error',
          message: error.errors[0]?.message || 'Invalid input',
          details: error.errors
        });
      }
      
      res.status(500).json({
        success: false,
        error: 'Save failed',
        message: error instanceof Error ? error.message : 'Failed to save reports'
      });
    }
  }
);

/**
 * GET /api/v2/export/formats
 * Get available export formats and their capabilities
 */
router.get('/formats', (req, res) => {
  res.json({
    success: true,
    status: 200,
    data: {
      formats: [
        {
          name: 'markdown',
          extension: 'md',
          mimeType: 'text/markdown',
          description: 'Human-readable Markdown format with embedded Mermaid diagrams',
          features: ['mermaid_diagrams', 'tables', 'links', 'formatting'],
          maxSize: '1MB',
        },
        {
          name: 'pdf',
          extension: 'pdf',
          mimeType: 'application/pdf',
          description: 'Professional PDF report with rendered charts and formatting',
          features: ['rendered_diagrams', 'professional_layout', 'print_ready', 'embedded_fonts'],
          maxSize: '10MB',
        }
      ],
      limits: {
        rateLimit: '20 requests per hour',
        maxReportAge: '90 days',
        authentication: 'Optional (higher limits for authenticated users)',
      },
      endpoints: {
        markdown: 'GET /api/v2/export/:checkId/markdown',
        pdf: 'GET /api/v2/export/:checkId/pdf',
        save: 'POST /api/v2/export/:checkId/save',
      }
    },
    meta: {
      version: 'v2',
      feature: 'export-formats',
    }
  });
});

/**
 * DELETE /api/v2/export/cleanup
 * Clean up old report files (admin only)
 */
router.delete('/cleanup', 
  requireAuth, 
  async (req: AuthenticatedRequest, res) => {
    try {
      // TODO: Add proper admin role checking in future phases
      const { maxAgeHours = 24 } = z.object({
        maxAgeHours: z.number().min(1).max(168).default(24), // 1 hour to 1 week
      }).parse(req.body);
      
      logger.info('Starting report cleanup', {
        userId: req.user!.id,
        maxAgeHours,
      });
      
      await exportService.cleanupOldReports(maxAgeHours);
      
      logger.info('Report cleanup completed', {
        userId: req.user!.id,
        maxAgeHours,
      });
      
      res.json({
        success: true,
        status: 200,
        data: {
          message: 'Cleanup completed successfully',
          maxAgeHours,
          cleanupTime: new Date().toISOString(),
        },
        meta: {
          version: 'v2',
          feature: 'export-cleanup',
        }
      });
      
    } catch (error) {
      logger.error('Report cleanup failed:', error);
      
      if (error instanceof z.ZodError) {
        return res.status(400).json({
          success: false,
          error: 'Validation error',
          message: error.errors[0]?.message || 'Invalid input',
          details: error.errors
        });
      }
      
      res.status(500).json({
        success: false,
        error: 'Cleanup failed',
        message: error instanceof Error ? error.message : 'Failed to cleanup reports'
      });
    }
  }
);

export default router;
