import express from 'express';
import { verifyFirebaseToken } from '../middleware/firebaseAuth';
import { documentController } from '../controllers/documentController';
import { unifiedDocumentProcessor } from '../services/unifiedDocumentProcessor';
import { logger } from '../utils/logger';
import { config } from '../config/env';
import { handleFileUpload } from '../middleware/upload';
import { DocumentModel } from '../models/DocumentModel';
import { validateUUID, addCorrelationId } from '../middleware/validation';

// Extend Express Request to include user property
declare global {
  namespace Express {
    interface Request {
      user?: import('firebase-admin').auth.DecodedIdToken;
    }
  }
}

const router = express.Router();

// Apply authentication and correlation ID to all routes
router.use(verifyFirebaseToken);
router.use(addCorrelationId);

// Add logging middleware for document routes
router.use((req, res, next) => {
  console.log(`📄 Document route accessed: ${req.method} ${req.path}`);
  next();
});

// Analytics endpoints (MUST come before ANY routes with :id parameters)
router.get('/analytics', async (req, res) => {
  try {
    const userId = req.user?.uid;
    if (!userId) {
      return res.status(401).json({ 
        error: 'User not authenticated',
        correlationId: req.correlationId 
      });
    }

    const days = parseInt(req.query['days'] as string) || 30;
    // Import the service here to avoid circular dependencies
    const { agenticRAGDatabaseService } = await import('../services/agenticRAGDatabaseService');
    const analytics = await agenticRAGDatabaseService.getAnalyticsData(days);
    return res.json({
      ...analytics,
      correlationId: req.correlationId || undefined
    });
  } catch (error) {
    logger.error('Failed to get analytics data', { 
      error, 
      correlationId: req.correlationId 
    });
    return res.status(500).json({ 
      error: 'Failed to get analytics data',
      correlationId: req.correlationId || undefined
    });
  }
});

router.get('/processing-stats', async (req, res) => {
  try {
    const stats = await unifiedDocumentProcessor.getProcessingStats();
    return res.json({
      ...stats,
      correlationId: req.correlationId || undefined
    });
  } catch (error) {
    logger.error('Failed to get processing stats', { 
      error, 
      correlationId: req.correlationId 
    });
    return res.status(500).json({ 
      error: 'Failed to get processing stats',
      correlationId: req.correlationId || undefined
    });
  }
});

// NEW Firebase Storage direct upload routes
router.post('/upload-url', documentController.getUploadUrl);
router.post('/:id/confirm-upload', validateUUID('id'), documentController.confirmUpload);

// LEGACY multipart upload routes (keeping for backward compatibility)
router.post('/upload', handleFileUpload, documentController.uploadDocument);
router.post('/', handleFileUpload, documentController.uploadDocument);
router.get('/', documentController.getDocuments);

// Document-specific routes with UUID validation
router.get('/:id', validateUUID('id'), documentController.getDocument);
router.get('/:id/progress', validateUUID('id'), documentController.getDocumentProgress);
router.delete('/:id', validateUUID('id'), documentController.deleteDocument);

// Download endpoint (keeping this)
router.get('/:id/download', validateUUID('id'), async (req, res) => {
  try {
    const userId = req.user?.uid;
    if (!userId) {
      return res.status(401).json({ 
        error: 'User not authenticated',
        correlationId: req.correlationId 
      });
    }

    const { id } = req.params;
    if (!id) {
      return res.status(400).json({ 
        error: 'Document ID is required',
        correlationId: req.correlationId 
      });
    }
    const document = await DocumentModel.findById(id);
    
    if (!document) {
      return res.status(404).json({ 
        error: 'Document not found',
        correlationId: req.correlationId 
      });
    }

    if (document.user_id !== userId) {
      return res.status(403).json({ 
        error: 'Access denied',
        correlationId: req.correlationId 
      });
    }

    // Check if document has a PDF summary
    if (!document.summary_pdf_path) {
      return res.status(404).json({ 
        error: 'No PDF summary available for download',
        correlationId: req.correlationId 
      });
    }

    // Import file storage service
    const { fileStorageService } = await import('../services/fileStorageService');
    const fileBuffer = await fileStorageService.getFile(document.summary_pdf_path);
    
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', `attachment; filename="${document.original_file_name.replace(/\.[^/.]+$/, '')}_summary.pdf"`);
    res.setHeader('x-correlation-id', req.correlationId || 'unknown');
    return res.send(fileBuffer);

  } catch (error) {
    logger.error('Download document failed', { 
      error, 
      correlationId: req.correlationId 
    });
    return res.status(500).json({ 
      error: 'Download failed',
      correlationId: req.correlationId || undefined
    });
  }
});

// ONLY OPTIMIZED AGENTIC RAG PROCESSING ROUTE - All other processing routes disabled
router.post('/:id/process-optimized-agentic-rag', validateUUID('id'), async (req, res) => {
  try {
    const { id } = req.params;
    if (!id) {
      return res.status(400).json({ 
        error: 'Document ID is required',
        correlationId: req.correlationId 
      });
    }
    
    const userId = req.user?.uid;
    
    if (!userId) {
      return res.status(401).json({ 
        error: 'User not authenticated',
        correlationId: req.correlationId 
      });
    }

    // Check if agentic RAG is enabled
    if (!config.agenticRag.enabled) {
      return res.status(400).json({ 
        error: 'Agentic RAG is not enabled',
        correlationId: req.correlationId 
      });
    }

    // Get document text
    const documentText = await documentController.getDocumentText(id);
    
    const result = await unifiedDocumentProcessor.processDocument(
      id, 
      userId, 
      documentText, 
      { strategy: 'optimized_agentic_rag' }
    );

    return res.json({
      success: result.success,
      processingStrategy: result.processingStrategy,
      processingTime: result.processingTime,
      apiCalls: result.apiCalls,
      summary: result.summary,
      analysisData: result.analysisData,
      error: result.error,
      correlationId: req.correlationId || undefined
    });

  } catch (error) {
    logger.error('Optimized Agentic RAG processing failed', { 
      error, 
      correlationId: req.correlationId 
    });
    return res.status(500).json({ 
      error: 'Optimized Agentic RAG processing failed',
      correlationId: req.correlationId || undefined
    });
  }
});

// Agentic RAG session routes (keeping these for monitoring)
router.get('/:id/agentic-rag-sessions', validateUUID('id'), async (req, res) => {
  try {
    const { id } = req.params;
    if (!id) {
      return res.status(400).json({ 
        error: 'Document ID is required',
        correlationId: req.correlationId 
      });
    }
    
    const userId = req.user?.uid;
    
    if (!userId) {
      return res.status(401).json({ 
        error: 'User not authenticated',
        correlationId: req.correlationId 
      });
    }

    // Import the model here to avoid circular dependencies
    const { AgenticRAGSessionModel } = await import('../models/AgenticRAGModels');
    const sessions = await AgenticRAGSessionModel.getByDocumentId(id);
    
    return res.json({
      sessions: sessions.map(session => ({
        id: session.id,
        strategy: session.strategy,
        status: session.status,
        totalAgents: session.totalAgents,
        completedAgents: session.completedAgents,
        failedAgents: session.failedAgents,
        overallValidationScore: session.overallValidationScore,
        processingTimeMs: session.processingTimeMs,
        apiCallsCount: session.apiCallsCount,
        totalCost: session.totalCost,
        createdAt: session.createdAt,
        completedAt: session.completedAt
      })),
      correlationId: req.correlationId || undefined
    });

  } catch (error) {
    logger.error('Failed to get agentic RAG sessions', { 
      error, 
      correlationId: req.correlationId 
    });
    return res.status(500).json({ 
      error: 'Failed to get agentic RAG sessions',
      correlationId: req.correlationId || undefined
    });
  }
});

router.get('/agentic-rag-sessions/:sessionId', validateUUID('sessionId'), async (req, res) => {
  try {
    const { sessionId } = req.params;
    if (!sessionId) {
      return res.status(400).json({ 
        error: 'Session ID is required',
        correlationId: req.correlationId 
      });
    }
    
    const userId = req.user?.uid;
    
    if (!userId) {
      return res.status(401).json({ 
        error: 'User not authenticated',
        correlationId: req.correlationId 
      });
    }

    // Import the models here to avoid circular dependencies
    const { AgenticRAGSessionModel, AgentExecutionModel, QualityMetricsModel } = await import('../models/AgenticRAGModels');
    
    const session = await AgenticRAGSessionModel.getById(sessionId);
    if (!session) {
      return res.status(404).json({ 
        error: 'Session not found',
        correlationId: req.correlationId 
      });
    }

    // Get executions and quality metrics
    const executions = await AgentExecutionModel.getBySessionId(sessionId);
    const qualityMetrics = await QualityMetricsModel.getBySessionId(sessionId);
    
    return res.json({
      session: {
        id: session.id,
        strategy: session.strategy,
        status: session.status,
        totalAgents: session.totalAgents,
        completedAgents: session.completedAgents,
        failedAgents: session.failedAgents,
        overallValidationScore: session.overallValidationScore,
        processingTimeMs: session.processingTimeMs,
        apiCallsCount: session.apiCallsCount,
        totalCost: session.totalCost,
        createdAt: session.createdAt,
        completedAt: session.completedAt
      },
      executions: executions.map(execution => ({
        id: execution.id,
        agentName: execution.agentName,
        stepNumber: execution.stepNumber,
        status: execution.status,
        processingTimeMs: execution.processingTimeMs,
        retryCount: execution.retryCount,
        errorMessage: execution.errorMessage,
        createdAt: execution.createdAt,
        updatedAt: execution.updatedAt
      })),
      qualityMetrics: qualityMetrics.map(metric => ({
        id: metric.id,
        metricType: metric.metricType,
        metricValue: metric.metricValue,
        metricDetails: metric.metricDetails,
        createdAt: metric.createdAt
      })),
      correlationId: req.correlationId || undefined
    });

  } catch (error) {
    logger.error('Failed to get agentic RAG session details', { 
      error, 
      correlationId: req.correlationId 
    });
    return res.status(500).json({ 
      error: 'Failed to get agentic RAG session details',
      correlationId: req.correlationId || undefined
    });
  }
});

router.get('/:id/analytics', validateUUID('id'), async (req, res) => {
  try {
    const { id } = req.params;
    if (!id) {
      return res.status(400).json({ 
        error: 'Document ID is required',
        correlationId: req.correlationId 
      });
    }
    
    const userId = req.user?.uid;
    
    if (!userId) {
      return res.status(401).json({ 
        error: 'User not authenticated',
        correlationId: req.correlationId 
      });
    }

    // Import the service here to avoid circular dependencies
    const { agenticRAGDatabaseService } = await import('../services/agenticRAGDatabaseService');
    const analytics = await agenticRAGDatabaseService.getDocumentAnalytics(id);
    
    return res.json({
      ...analytics,
      correlationId: req.correlationId || undefined
    });
  } catch (error) {
    logger.error('Failed to get document analytics', { 
      error, 
      correlationId: req.correlationId 
    });
    return res.status(500).json({ 
      error: 'Failed to get document analytics',
      correlationId: req.correlationId || undefined
    });
  }
});

export default router; 