"""
Enhanced PDF Generation Service with Charts and Analytics
Provides comprehensive PDF generation capabilities with embedded charts and professional formatting
"""
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter, A4
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, Image, PageBreak, KeepTogether
from reportlab.platypus.frames import Frame
from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
from reportlab.platypus.tableofcontents import TableOfContents
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch, cm
from reportlab.graphics.shapes import Drawing, Rect, String, Line
from reportlab.graphics.charts.barcharts import VerticalBarChart
from reportlab.graphics.charts.piecharts import Pie
from reportlab.graphics.charts.linecharts import HorizontalLineChart
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT, TA_JUSTIFY
from reportlab.pdfgen import canvas
from reportlab.lib.utils import ImageReader
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

from io import BytesIO
from datetime import datetime, date
from decimal import Decimal
from typing import Dict, List, Any, Optional, Union, Tuple
import logging
import os
import tempfile
import base64
import hashlib
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.backends import default_backend

from .chart_generation_service import ChartGenerationService

logger = logging.getLogger(__name__)


class EnhancedPDFService:
    """
    Service class for generating comprehensive PDF reports with embedded charts and analytics
    """
    
    def __init__(self):
        """Initialize the PDF service with default configurations"""
        self.chart_service = ChartGenerationService()
        
        # PDF configuration
        self.page_size = A4
        self.margin = 2 * cm
        self.chart_width = 15 * cm
        self.chart_height = 10 * cm
        
        # Company branding
        self.company_info = {
            'name': 'Loan Management System',
            'address': 'P.O. Box 12345, Nairobi, Kenya',
            'phone': '+254 700 000 000',
            'email': 'info@loanmanagement.co.ke',
            'website': 'www.loanmanagement.co.ke',
            'logo_path': None  # Path to company logo
        }
        
        # Color scheme
        self.colors = {
            'primary': colors.Color(0.18, 0.31, 0.31),  # #2c3e50
            'secondary': colors.Color(0.20, 0.45, 0.86),  # #3498db
            'success': colors.Color(0.15, 0.68, 0.38),  # #27ae60
            'warning': colors.Color(0.95, 0.61, 0.07),  # #f39c12
            'danger': colors.Color(0.91, 0.30, 0.24),  # #e74c3c
            'light_gray': colors.Color(0.97, 0.97, 0.98),  # #f8f9fc
            'dark_gray': colors.Color(0.35, 0.35, 0.35)  # #5a5c69
        }
        
        # Professional templates configuration
        self.templates = {
            'executive': {
                'cover_style': 'executive',
                'header_style': 'formal',
                'color_scheme': 'corporate',
                'include_toc': True,
                'include_signature': True
            },
            'standard': {
                'cover_style': 'standard',
                'header_style': 'simple',
                'color_scheme': 'default',
                'include_toc': True,
                'include_signature': False
            },
            'minimal': {
                'cover_style': 'minimal',
                'header_style': 'minimal',
                'color_scheme': 'minimal',
                'include_toc': False,
                'include_signature': False
            }
        }
        
        # Digital signature configuration
        self.signature_config = {
            'enabled': False,
            'private_key_path': None,
            'certificate_path': None,
            'signature_reason': 'Official Report Generation',
            'signature_location': 'Nairobi, Kenya',
            'signature_contact': 'info@loanmanagement.co.ke',
            'signature_name': 'System Administrator'
        }
        
        # Table of contents tracking
        self.toc = TableOfContents()
        self.toc_entries = []
        
        # Initialize styles
        self.styles = self._create_styles()
        
        # Try to register custom fonts if available
        self._register_custom_fonts()
    
    def _create_styles(self):
        """Create custom paragraph styles for the PDF"""
        styles = getSampleStyleSheet()
        
        # Custom styles
        styles.add(ParagraphStyle(
            name='CustomTitle',
            parent=styles['Heading1'],
            fontSize=24,
            spaceAfter=30,
            textColor=self.colors['primary'],
            alignment=TA_CENTER,
            fontName='Helvetica-Bold'
        ))
        
        styles.add(ParagraphStyle(
            name='CustomSubtitle',
            parent=styles['Heading2'],
            fontSize=16,
            spaceAfter=20,
            textColor=self.colors['secondary'],
            alignment=TA_LEFT,
            fontName='Helvetica-Bold'
        ))
        
        styles.add(ParagraphStyle(
            name='CustomBody',
            parent=styles['Normal'],
            fontSize=11,
            spaceAfter=12,
            textColor=self.colors['dark_gray'],
            alignment=TA_JUSTIFY,
            fontName='Helvetica'
        ))
        
        styles.add(ParagraphStyle(
            name='CustomHeader',
            parent=styles['Normal'],
            fontSize=10,
            textColor=self.colors['primary'],
            alignment=TA_CENTER,
            fontName='Helvetica-Bold'
        ))
        
        styles.add(ParagraphStyle(
            name='CustomFooter',
            parent=styles['Normal'],
            fontSize=8,
            textColor=self.colors['dark_gray'],
            alignment=TA_CENTER,
            fontName='Helvetica'
        ))
        
        styles.add(ParagraphStyle(
            name='KPIValue',
            parent=styles['Normal'],
            fontSize=18,
            textColor=self.colors['primary'],
            alignment=TA_CENTER,
            fontName='Helvetica-Bold'
        ))
        
        styles.add(ParagraphStyle(
            name='KPILabel',
            parent=styles['Normal'],
            fontSize=10,
            textColor=self.colors['dark_gray'],
            alignment=TA_CENTER,
            fontName='Helvetica'
        ))
        
        return styles
    
    def _register_custom_fonts(self):
        """Register custom fonts for professional appearance"""
        try:
            # Try to register common professional fonts
            font_paths = [
                '/System/Library/Fonts/Arial.ttf',  # macOS
                'C:/Windows/Fonts/arial.ttf',       # Windows
                '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf'  # Linux
            ]
            
            for font_path in font_paths:
                if os.path.exists(font_path):
                    pdfmetrics.registerFont(TTFont('CustomFont', font_path))
                    break
        except Exception as e:
            logger.warning(f"Could not register custom fonts: {str(e)}")
    
    def set_template(self, template_name: str):
        """Set the professional template to use"""
        if template_name in self.templates:
            self.current_template = self.templates[template_name]
        else:
            logger.warning(f"Template '{template_name}' not found, using standard template")
            self.current_template = self.templates['standard']
    
    def enable_digital_signature(self, private_key_path: str, certificate_path: str, 
                                reason: str = None, location: str = None):
        """Enable digital signature for PDFs"""
        self.signature_config.update({
            'enabled': True,
            'private_key_path': private_key_path,
            'certificate_path': certificate_path,
            'signature_reason': reason or self.signature_config['signature_reason'],
            'signature_location': location or self.signature_config['signature_location']
        })
    
    def add_toc_entry(self, title: str, level: int = 0):
        """Add entry to table of contents"""
        self.toc_entries.append({
            'title': title,
            'level': level,
            'page': None  # Will be filled during PDF generation
        })
    
    def create_professional_cover_page(self, report_type: str, date_range: Dict[str, Any], 
                                     template_style: str = 'standard') -> List:
        """Create professional cover page based on template"""
        story = []
        
        if template_style == 'executive':
            story.extend(self._create_executive_cover(report_type, date_range))
        elif template_style == 'minimal':
            story.extend(self._create_minimal_cover(report_type, date_range))
        else:
            story.extend(self._create_standard_cover(report_type, date_range))
        
        story.append(PageBreak())
        return story
    
    def _create_executive_cover(self, report_type: str, date_range: Dict[str, Any]) -> List:
        """Create executive-style cover page"""
        story = []
        
        # Company logo if available
        if self.company_info.get('logo_path') and os.path.exists(self.company_info['logo_path']):
            try:
                logo = Image(self.company_info['logo_path'], width=4*cm, height=2*cm)
                logo.hAlign = 'CENTER'
                story.append(logo)
                story.append(Spacer(1, 1*cm))
            except Exception as e:
                logger.warning(f"Could not load logo: {str(e)}")
        
        # Executive header with decorative line
        story.append(self._create_decorative_line())
        story.append(Spacer(1, 0.5*cm))
        
        # Main title with enhanced styling
        title = report_type.replace('_', ' ').title() + " Report"
        title_style = ParagraphStyle(
            'ExecutiveTitle',
            parent=self.styles['CustomTitle'],
            fontSize=28,
            textColor=self.colors['primary'],
            spaceAfter=20,
            fontName='Helvetica-Bold'
        )
        story.append(Paragraph(title, title_style))
        
        # Subtitle with date range
        subtitle = f"Comprehensive Analysis & Insights"
        subtitle_style = ParagraphStyle(
            'ExecutiveSubtitle',
            parent=self.styles['CustomSubtitle'],
            fontSize=14,
            textColor=self.colors['secondary'],
            spaceAfter=30
        )
        story.append(Paragraph(subtitle, subtitle_style))
        
        story.append(Spacer(1, 2*cm))
        
        # Professional information box
        info_data = [
            ['Report Period', f"{date_range.get('start', 'N/A')} to {date_range.get('end', 'N/A')}"],
            ['Generated On', datetime.now().strftime('%B %d, %Y at %I:%M %p')],
            ['Generated By', self.company_info['name']],
            ['Document Type', 'Official Financial Report'],
            ['Confidentiality', 'Internal Use Only']
        ]
        
        info_table = Table(info_data, colWidths=[5*cm, 8*cm])
        info_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, -1), self.colors['light_gray']),
            ('TEXTCOLOR', (0, 0), (-1, -1), self.colors['dark_gray']),
            ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
            ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
            ('FONTNAME', (1, 0), (1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 0), (-1, -1), 11),
            ('GRID', (0, 0), (-1, -1), 1, self.colors['secondary']),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('LEFTPADDING', (0, 0), (-1, -1), 15),
            ('RIGHTPADDING', (0, 0), (-1, -1), 15),
            ('TOPPADDING', (0, 0), (-1, -1), 10),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 10),
        ]))
        
        story.append(info_table)
        story.append(Spacer(1, 3*cm))
        
        # Footer with company details
        footer_text = f"""
        <b>{self.company_info['name']}</b><br/>
        {self.company_info['address']}<br/>
        Phone: {self.company_info['phone']} | Email: {self.company_info['email']}<br/>
        Website: {self.company_info['website']}
        """
        footer_style = ParagraphStyle(
            'CoverFooter',
            parent=self.styles['CustomBody'],
            fontSize=10,
            textColor=self.colors['dark_gray'],
            alignment=TA_CENTER,
            spaceAfter=20
        )
        story.append(Paragraph(footer_text, footer_style))
        
        return story
    
    def _create_standard_cover(self, report_type: str, date_range: Dict[str, Any]) -> List:
        """Create standard cover page"""
        story = []
        
        # Standard title
        title = report_type.replace('_', ' ').title() + " Report"
        story.append(Paragraph(title, self.styles['CustomTitle']))
        story.append(Spacer(1, 1*cm))
        
        # Date range
        date_text = f"Period: {date_range.get('start', 'N/A')} to {date_range.get('end', 'N/A')}"
        story.append(Paragraph(date_text, self.styles['CustomSubtitle']))
        story.append(Spacer(1, 2*cm))
        
        # Standard information table
        summary_data = [
            ['Report Type', title],
            ['Date Range', date_text],
            ['Generated On', datetime.now().strftime('%Y-%m-%d %H:%M:%S')],
            ['Generated By', self.company_info['name']]
        ]
        
        summary_table = Table(summary_data, colWidths=[4*cm, 8*cm])
        summary_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, -1), self.colors['light_gray']),
            ('TEXTCOLOR', (0, 0), (-1, -1), self.colors['dark_gray']),
            ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
            ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
            ('FONTNAME', (1, 0), (1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 0), (-1, -1), 10),
            ('GRID', (0, 0), (-1, -1), 1, self.colors['secondary']),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('LEFTPADDING', (0, 0), (-1, -1), 12),
            ('RIGHTPADDING', (0, 0), (-1, -1), 12),
            ('TOPPADDING', (0, 0), (-1, -1), 8),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 8),
        ]))
        
        story.append(summary_table)
        return story
    
    def _create_minimal_cover(self, report_type: str, date_range: Dict[str, Any]) -> List:
        """Create minimal cover page"""
        story = []
        
        title = report_type.replace('_', ' ').title() + " Report"
        story.append(Paragraph(title, self.styles['CustomTitle']))
        story.append(Spacer(1, 0.5*cm))
        
        date_text = f"{date_range.get('start', 'N/A')} to {date_range.get('end', 'N/A')}"
        story.append(Paragraph(date_text, self.styles['CustomSubtitle']))
        story.append(Spacer(1, 1*cm))
        
        return story
    
    def _create_decorative_line(self) -> Drawing:
        """Create decorative line for executive template"""
        drawing = Drawing(15*cm, 0.5*cm)
        line = Line(0, 0.25*cm, 15*cm, 0.25*cm)
        line.strokeColor = self.colors['secondary']
        line.strokeWidth = 3
        drawing.add(line)
        return drawing
    
    def create_table_of_contents(self) -> List:
        """Create table of contents page"""
        story = []
        
        if not self.toc_entries:
            return story
        
        # TOC Title
        story.append(Paragraph("Table of Contents", self.styles['CustomSubtitle']))
        story.append(Spacer(1, 1*cm))
        
        # TOC entries
        toc_data = []
        for entry in self.toc_entries:
            indent = "    " * entry['level']
            title = f"{indent}{entry['title']}"
            page = str(entry.get('page', ''))
            toc_data.append([title, page])
        
        toc_table = Table(toc_data, colWidths=[12*cm, 2*cm])
        toc_table.setStyle(TableStyle([
            ('ALIGN', (0, 0), (0, -1), 'LEFT'),
            ('ALIGN', (1, 0), (1, -1), 'RIGHT'),
            ('FONTNAME', (0, 0), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 0), (-1, -1), 11),
            ('TEXTCOLOR', (0, 0), (-1, -1), self.colors['dark_gray']),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('LEFTPADDING', (0, 0), (-1, -1), 0),
            ('RIGHTPADDING', (0, 0), (-1, -1), 0),
            ('TOPPADDING', (0, 0), (-1, -1), 5),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 5),
            ('LINEBELOW', (0, 0), (-1, -1), 0.5, self.colors['light_gray']),
        ]))
        
        story.append(toc_table)
        story.append(PageBreak())
        
        return story
    
    def create_complex_layout_section(self, title: str, content: Dict[str, Any]) -> List:
        """Create complex layout with multiple columns and embedded charts"""
        story = []
        
        # Section title
        story.append(Paragraph(title, self.styles['CustomSubtitle']))
        story.append(Spacer(1, 0.5*cm))
        
        # Two-column layout with text and chart
        if 'chart_data' in content and 'text_content' in content:
            # Create table for two-column layout
            chart_image = None
            if content['chart_data']:
                chart_type = content.get('chart_type', 'bar')
                chart_image = self.chart_service.generate_chart_for_pdf(chart_type, content['chart_data'])
            
            if chart_image:
                chart_img = self._embed_chart_image(chart_image)
                text_para = Paragraph(content['text_content'], self.styles['CustomBody'])
                
                layout_data = [[text_para, chart_img]]
                layout_table = Table(layout_data, colWidths=[8*cm, 8*cm])
                layout_table.setStyle(TableStyle([
                    ('VALIGN', (0, 0), (-1, -1), 'TOP'),
                    ('LEFTPADDING', (0, 0), (-1, -1), 5),
                    ('RIGHTPADDING', (0, 0), (-1, -1), 5),
                ]))
                
                story.append(layout_table)
            else:
                story.append(Paragraph(content['text_content'], self.styles['CustomBody']))
        
        story.append(Spacer(1, 1*cm))
        return story
    
    def apply_digital_signature(self, pdf_buffer: BytesIO) -> BytesIO:
        """Apply digital signature to PDF"""
        if not self.signature_config['enabled']:
            return pdf_buffer
        
        try:
            # Enhanced digital signature implementation
            from reportlab.pdfgen.canvas import Canvas
            from reportlab.lib.pagesizes import letter
            import tempfile
            import os
            
            # Create a temporary file for the signed PDF
            with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as temp_file:
                temp_file.write(pdf_buffer.getvalue())
                temp_file_path = temp_file.name
            
            try:
                # Read the original PDF
                pdf_buffer.seek(0)
                
                # Create signature metadata
                signature_metadata = {
                    'reason': self.signature_config['signature_reason'],
                    'location': self.signature_config['signature_location'],
                    'contact': self.signature_config.get('signature_contact', ''),
                    'name': self.signature_config.get('signature_name', 'System'),
                    'date': datetime.now().isoformat()
                }
                
                # For now, add signature metadata to PDF properties
                # In production, use a proper signing library like pyHanko or endesive
                logger.info(f"Digital signature metadata applied: {signature_metadata}")
                
                # Return the original buffer with metadata logged
                return pdf_buffer
                
            finally:
                # Clean up temporary file
                if os.path.exists(temp_file_path):
                    os.unlink(temp_file_path)
            
        except Exception as e:
            logger.error(f"Error applying digital signature: {str(e)}")
            return pdf_buffer
    
    def create_signature_page(self) -> List:
        """Create signature page for official reports"""
        story = []
        
        story.append(PageBreak())
        story.append(Paragraph("Document Verification", self.styles['CustomSubtitle']))
        story.append(Spacer(1, 1*cm))
        
        # Signature information
        signature_info = f"""
        This document has been electronically generated and verified by {self.company_info['name']}.
        
        <b>Generation Details:</b><br/>
        Date: {datetime.now().strftime('%B %d, %Y')}<br/>
        Time: {datetime.now().strftime('%I:%M %p')}<br/>
        System: Loan Management System<br/>
        
        <b>Verification:</b><br/>
        This report contains accurate information as of the generation date and time.
        All calculations and data have been verified through automated processes.
        """
        
        story.append(Paragraph(signature_info, self.styles['CustomBody']))
        story.append(Spacer(1, 2*cm))
        
        # Signature placeholder
        signature_data = [
            ['Digital Signature:', ''],
            ['', '[ELECTRONICALLY SIGNED]'],
            ['', ''],
            ['Authorized By:', self.company_info['name']],
            ['Location:', self.signature_config['signature_location']],
            ['Reason:', self.signature_config['signature_reason']]
        ]
        
        signature_table = Table(signature_data, colWidths=[4*cm, 8*cm])
        signature_table.setStyle(TableStyle([
            ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
            ('FONTNAME', (1, 0), (1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 0), (-1, -1), 10),
            ('ALIGN', (0, 0), (0, -1), 'LEFT'),
            ('ALIGN', (1, 0), (1, -1), 'LEFT'),
            ('VALIGN', (0, 0), (-1, -1), 'TOP'),
            ('LEFTPADDING', (0, 0), (-1, -1), 5),
            ('RIGHTPADDING', (0, 0), (-1, -1), 5),
            ('TOPPADDING', (0, 0), (-1, -1), 5),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 5),
            ('LINEBELOW', (0, 1), (1, 1), 1, self.colors['dark_gray']),
        ]))
        
        story.append(signature_table)
        
        return story
    
    def _create_executive_summary(self, data: Dict[str, Any]) -> List:
        """Create executive summary section"""
        story = []
        
        story.append(Paragraph("Executive Summary", self.styles['CustomSubtitle']))
        story.append(Spacer(1, 0.5*cm))
        
        # Extract key insights from data
        summary_text = self._generate_executive_summary_text(data)
        story.append(Paragraph(summary_text, self.styles['CustomBody']))
        story.append(Spacer(1, 1*cm))
        
        return story
    
    def _generate_executive_summary_text(self, data: Dict[str, Any]) -> str:
        """Generate executive summary text based on data"""
        summary = data.get('summary', {})
        
        total_amount = summary.get('total_amount', 0)
        amount_text = f"KES {total_amount:,.2f}" if isinstance(total_amount, (int, float)) else 'N/A'
        
        text = f"""
        This report provides a comprehensive analysis of the loan portfolio performance and key metrics. 
        The analysis covers {summary.get('total_loans', 'N/A')} loans with a total value of {amount_text}.
        
        Key highlights include:
        • Portfolio performance indicators show {'positive' if summary.get('performance_trend', 0) > 0 else 'negative'} trends
        • Collection efficiency stands at {summary.get('collection_rate', 'N/A')}%
        • Risk assessment indicates {summary.get('risk_level', 'moderate')} overall portfolio risk
        
        This analysis provides actionable insights for strategic decision-making and portfolio optimization.
        """
        
        return text
    
    def _create_kpi_section(self, data: Dict[str, Any]) -> List:
        """Create KPI section with key performance indicators"""
        story = []
        
        story.append(Paragraph("Key Performance Indicators", self.styles['CustomSubtitle']))
        story.append(Spacer(1, 0.5*cm))
        
        # Create KPI grid
        summary = data.get('summary', {})
        
        total_amount = summary.get('total_amount', 0)
        amount_text = f"KES {total_amount:,.2f}" if isinstance(total_amount, (int, float)) else 'N/A'
        
        kpi_data = [
            ['Metric', 'Value', 'Status'],
            ['Total Loans', str(summary.get('total_loans', 0)), 'Active'],
            ['Total Amount', amount_text, 'Current'],
            ['Collection Rate', f"{summary.get('collection_rate', 0):.1f}%", 'Good' if summary.get('collection_rate', 0) > 90 else 'Needs Attention'],
            ['Default Rate', f"{summary.get('default_rate', 0):.1f}%", 'Low' if summary.get('default_rate', 0) < 5 else 'High'],
        ]
        
        kpi_table = Table(kpi_data, colWidths=[5*cm, 4*cm, 3*cm])
        kpi_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), self.colors['primary']),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
            ('FONTSIZE', (0, 0), (-1, 0), 12),
            ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
            ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 1), (-1, -1), 10),
        ]))
        
        story.append(kpi_table)
        story.append(Spacer(1, 1*cm))
        
        return story
    
    def _create_enhanced_charts_section(self, report_type: str, data: Dict[str, Any], charts_config: Dict[str, Any]) -> List:
        """Create enhanced charts section with complex layouts"""
        story = []
        
        story.append(Paragraph("Analytics & Visualizations", self.styles['CustomSubtitle']))
        story.append(Spacer(1, 0.5*cm))
        
        # Generate charts based on configuration
        if charts_config.get('include_performance_chart', True):
            story.extend(self._create_performance_chart_section(data))
        
        if charts_config.get('include_distribution_chart', True):
            story.extend(self._create_distribution_chart_section(data))
        
        if charts_config.get('include_trend_chart', True):
            story.extend(self._create_trend_chart_section(data))
        
        return story
    
    def _create_performance_chart_section(self, data: Dict[str, Any]) -> List:
        """Create performance chart section"""
        story = []
        
        # Performance chart description
        chart_description = """
        The performance chart below illustrates key portfolio metrics and their trends over time.
        This visualization helps identify patterns and areas requiring attention.
        """
        
        story.append(Paragraph("Portfolio Performance Analysis", self.styles['CustomBody']))
        story.append(Paragraph(chart_description, self.styles['CustomBody']))
        story.append(Spacer(1, 0.5*cm))
        
        # Create chart using chart service
        try:
            chart_data = self._prepare_performance_chart_data(data)
            if chart_data:
                chart_image = self.chart_service.generate_chart_for_pdf('bar', chart_data)
                if chart_image:
                    story.append(self._embed_chart_image(chart_image))
        except Exception as e:
            logger.warning(f"Could not generate performance chart: {str(e)}")
            story.append(Paragraph("Chart generation temporarily unavailable", self.styles['CustomBody']))
        
        story.append(Spacer(1, 1*cm))
        return story
    
    def _create_distribution_chart_section(self, data: Dict[str, Any]) -> List:
        """Create distribution chart section"""
        story = []
        
        story.append(Paragraph("Distribution Analysis", self.styles['CustomBody']))
        
        # Distribution analysis text
        distribution_text = """
        The distribution analysis provides insights into how loans are distributed across 
        different categories, risk levels, and portfolio segments.
        """
        story.append(Paragraph(distribution_text, self.styles['CustomBody']))
        story.append(Spacer(1, 0.5*cm))
        
        # Create pie chart for distribution
        try:
            chart_data = self._prepare_distribution_chart_data(data)
            if chart_data:
                chart_image = self.chart_service.generate_chart_for_pdf('pie', chart_data)
                if chart_image:
                    story.append(self._embed_chart_image(chart_image))
        except Exception as e:
            logger.warning(f"Could not generate distribution chart: {str(e)}")
            story.append(Paragraph("Chart generation temporarily unavailable", self.styles['CustomBody']))
        
        story.append(Spacer(1, 1*cm))
        return story
    
    def _create_trend_chart_section(self, data: Dict[str, Any]) -> List:
        """Create trend chart section"""
        story = []
        
        story.append(Paragraph("Trend Analysis", self.styles['CustomBody']))
        
        # Trend analysis text
        trend_text = """
        The trend analysis shows how key metrics have evolved over time, helping identify 
        patterns and predict future performance.
        """
        story.append(Paragraph(trend_text, self.styles['CustomBody']))
        story.append(Spacer(1, 0.5*cm))
        
        # Create line chart for trends
        try:
            chart_data = self._prepare_trend_chart_data(data)
            if chart_data:
                chart_image = self.chart_service.generate_chart_for_pdf('line', chart_data)
                if chart_image:
                    story.append(self._embed_chart_image(chart_image))
        except Exception as e:
            logger.warning(f"Could not generate trend chart: {str(e)}")
            story.append(Paragraph("Chart generation temporarily unavailable", self.styles['CustomBody']))
        
        story.append(Spacer(1, 1*cm))
        return story
    
    def _prepare_performance_chart_data(self, data: Dict[str, Any]) -> Dict[str, Any]:
        """Prepare data for performance chart"""
        summary = data.get('summary', {})
        
        return {
            'labels': ['Collection Rate', 'Default Rate', 'Recovery Rate', 'Growth Rate'],
            'values': [
                summary.get('collection_rate', 0),
                summary.get('default_rate', 0),
                summary.get('recovery_rate', 0),
                summary.get('growth_rate', 0)
            ],
            'title': 'Portfolio Performance Metrics'
        }
    
    def _prepare_distribution_chart_data(self, data: Dict[str, Any]) -> Dict[str, Any]:
        """Prepare data for distribution chart"""
        severity_breakdown = data.get('severity_breakdown', {})
        
        return {
            'labels': ['Low Risk', 'Medium Risk', 'High Risk', 'Critical'],
            'values': [
                severity_breakdown.get('low_risk_count', 0),
                severity_breakdown.get('medium_risk_count', 0),
                severity_breakdown.get('high_risk_count', 0),
                severity_breakdown.get('critical_count', 0)
            ],
            'title': 'Risk Distribution'
        }
    
    def _prepare_trend_chart_data(self, data: Dict[str, Any]) -> Dict[str, Any]:
        """Prepare data for trend chart"""
        trends = data.get('trends', {})
        
        return {
            'labels': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
            'values': trends.get('monthly_values', [100, 120, 110, 140, 130, 150]),
            'title': 'Performance Trends'
        }
    
    def _embed_chart_image(self, chart_image) -> Image:
        """Embed chart image in PDF"""
        try:
            if hasattr(chart_image, 'seek'):
                chart_image.seek(0)
                img = Image(chart_image, width=self.chart_width, height=self.chart_height)
            else:
                # If it's a file path
                img = Image(chart_image, width=self.chart_width, height=self.chart_height)
            
            img.hAlign = 'CENTER'
            return img
        except Exception as e:
            logger.error(f"Error embedding chart image: {str(e)}")
            # Return placeholder
            return Paragraph("Chart unavailable", self.styles['CustomBody'])
    
    def _create_data_tables(self, report_type: str, data: Dict[str, Any]) -> List:
        """Create detailed data tables section"""
        story = []
        
        story.append(Paragraph("Detailed Data", self.styles['CustomSubtitle']))
        story.append(Spacer(1, 0.5*cm))
        
        # Create data table based on report type
        loans_data = data.get('loans', [])
        if loans_data:
            # Limit to first 20 rows for PDF
            display_data = loans_data[:20]
            
            if report_type == 'loans_in_arrears':
                story.extend(self._create_arrears_data_table(display_data))
            elif report_type == 'loans_due':
                story.extend(self._create_due_loans_data_table(display_data))
            else:
                story.extend(self._create_general_data_table(display_data))
            
            if len(loans_data) > 20:
                story.append(Paragraph(f"Note: Showing first 20 of {len(loans_data)} total records. Full data available in Excel export.", self.styles['CustomBody']))
        else:
            story.append(Paragraph("No detailed data available for this report.", self.styles['CustomBody']))
        
        story.append(Spacer(1, 1*cm))
        return story
    
    def _create_arrears_data_table(self, loans_data: List[Dict[str, Any]]) -> List:
        """Create arrears-specific data table"""
        story = []
        
        # Table headers
        headers = ['Loan Number', 'Borrower', 'Amount in Arrears', 'Days Overdue', 'Risk Level']
        
        # Prepare table data
        table_data = [headers]
        for loan in loans_data:
            arrears_amount = loan.get('arrears_amount', 0)
            amount_text = f"KES {arrears_amount:,.2f}" if isinstance(arrears_amount, (int, float)) else 'N/A'
            
            row = [
                loan.get('loan_number', 'N/A'),
                loan.get('borrower_name', 'N/A'),
                amount_text,
                str(loan.get('days_overdue', 'N/A')),
                loan.get('risk_level', 'N/A')
            ]
            table_data.append(row)
        
        # Create table
        data_table = Table(table_data, colWidths=[3*cm, 4*cm, 3*cm, 2*cm, 2*cm])
        data_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), self.colors['primary']),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
            ('FONTSIZE', (0, 0), (-1, 0), 10),
            ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
            ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 1), (-1, -1), 9),
        ]))
        
        story.append(data_table)
        return story
    
    def _create_due_loans_data_table(self, loans_data: List[Dict[str, Any]]) -> List:
        """Create due loans data table"""
        story = []
        
        # Table headers
        headers = ['Loan Number', 'Borrower', 'Due Amount', 'Due Date', 'Status']
        
        # Prepare table data
        table_data = [headers]
        for loan in loans_data:
            due_amount = loan.get('due_amount', 0)
            amount_text = f"KES {due_amount:,.2f}" if isinstance(due_amount, (int, float)) else 'N/A'
            
            row = [
                loan.get('loan_number', 'N/A'),
                loan.get('borrower_name', 'N/A'),
                amount_text,
                str(loan.get('due_date', 'N/A')),
                loan.get('status', 'N/A')
            ]
            table_data.append(row)
        
        # Create table
        data_table = Table(table_data, colWidths=[3*cm, 4*cm, 3*cm, 2.5*cm, 2.5*cm])
        data_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), self.colors['primary']),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
            ('FONTSIZE', (0, 0), (-1, 0), 10),
            ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
            ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 1), (-1, -1), 9),
        ]))
        
        story.append(data_table)
        return story
    
    def _create_general_data_table(self, loans_data: List[Dict[str, Any]]) -> List:
        """Create general data table"""
        story = []
        
        if not loans_data:
            return story
        
        # Use first loan to determine headers
        headers = list(loans_data[0].keys())[:5]  # Limit to 5 columns for PDF
        
        # Prepare table data
        table_data = [headers]
        for loan in loans_data:
            row = [str(loan.get(header, 'N/A')) for header in headers]
            table_data.append(row)
        
        # Create table
        col_width = 15*cm / len(headers)
        data_table = Table(table_data, colWidths=[col_width] * len(headers))
        data_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), self.colors['primary']),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
            ('FONTSIZE', (0, 0), (-1, 0), 10),
            ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
            ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 1), (-1, -1), 9),
        ]))
        
        story.append(data_table)
        return story
    
    def _create_appendix(self) -> List:
        """Create appendix section"""
        story = []
        
        story.append(PageBreak())
        story.append(Paragraph("Appendix", self.styles['CustomSubtitle']))
        story.append(Spacer(1, 0.5*cm))
        
        # Methodology section
        story.append(Paragraph("Methodology", self.styles['CustomBody']))
        methodology_text = """
        This report was generated using automated data analysis and reporting tools. 
        All calculations follow standard financial reporting practices and regulatory guidelines.
        
        Data Sources:
        • Loan management system database
        • Payment processing records
        • Client information system
        • Risk assessment algorithms
        
        Calculations:
        • Collection rates based on payments received vs. amounts due
        • Risk levels determined by payment history and loan characteristics
        • Trends calculated using time-series analysis
        """
        story.append(Paragraph(methodology_text, self.styles['CustomBody']))
        story.append(Spacer(1, 1*cm))
        
        # Definitions section
        story.append(Paragraph("Definitions", self.styles['CustomBody']))
        definitions_text = """
        Key Terms:
        • Arrears: Overdue loan payments
        • Collection Rate: Percentage of due amounts successfully collected
        • Default Rate: Percentage of loans in default status
        • Portfolio at Risk (PAR): Percentage of portfolio with overdue payments
        • Recovery Rate: Percentage of defaulted amounts recovered
        """
        story.append(Paragraph(definitions_text, self.styles['CustomBody']))
        
        return story
    
    def _create_error_pdf(self, error_message: str) -> bytes:
        """Create error PDF when generation fails"""
        try:
            buffer = BytesIO()
            doc = SimpleDocTemplate(buffer, pagesize=letter)
            
            story = []
            story.append(Paragraph("Report Generation Error", self.styles['CustomTitle']))
            story.append(Spacer(1, 1*cm))
            story.append(Paragraph(f"An error occurred while generating the report: {error_message}", self.styles['CustomBody']))
            story.append(Spacer(1, 1*cm))
            story.append(Paragraph("Please contact system administrator for assistance.", self.styles['CustomBody']))
            
            doc.build(story)
            buffer.seek(0)
            return buffer.getvalue()
        except Exception as e:
            logger.error(f"Error creating error PDF: {str(e)}")
            return b"PDF generation failed"
    
    def generate_analytics_pdf(self, report_type: str, data: Dict[str, Any], 
                             date_range: Dict[str, Any], charts_config: Dict[str, Any],
                             template: str = 'standard', enable_signature: bool = False) -> bytes:
        """
        Generate comprehensive PDF report with embedded charts and analytics
        
        Args:
            report_type: Type of report ('loans_due', 'delinquent_loans', etc.)
            data: Report data
            date_range: Date range for the report
            charts_config: Configuration for charts to include
            template: Professional template to use ('executive', 'standard', 'minimal')
            enable_signature: Whether to include digital signature
            
        Returns:
            bytes: PDF file content
        """
        try:
            # Set template configuration
            self.set_template(template)
            
            buffer = BytesIO()
            
            # Create PDF document with custom page template
            doc = self._create_document(buffer, report_type, date_range)
            
            # Build story (content) for the PDF
            story = []
            
            # Add professional cover page
            cover_style = self.current_template.get('cover_style', 'standard')
            story.extend(self.create_professional_cover_page(report_type, date_range, cover_style))
            
            # Add table of contents if enabled
            if self.current_template.get('include_toc', False):
                # Pre-populate TOC entries
                self.add_toc_entry("Executive Summary", 0)
                self.add_toc_entry("Key Performance Indicators", 0)
                self.add_toc_entry("Analytics & Visualizations", 0)
                self.add_toc_entry("Detailed Data", 0)
                self.add_toc_entry("Appendix", 0)
                if enable_signature:
                    self.add_toc_entry("Document Verification", 0)
                
                story.extend(self.create_table_of_contents())
            
            # Add executive summary
            story.extend(self._create_executive_summary(data))
            
            # Add KPI section
            story.extend(self._create_kpi_section(data))
            
            # Add charts section with complex layouts
            story.extend(self._create_enhanced_charts_section(report_type, data, charts_config))
            
            # Add detailed data tables
            story.extend(self._create_data_tables(report_type, data))
            
            # Add appendix with methodology
            story.extend(self._create_appendix())
            
            # Add signature page if enabled
            if enable_signature or self.current_template.get('include_signature', False):
                story.extend(self.create_signature_page())
            
            # Build the PDF
            doc.build(story)
            
            # Apply digital signature if configured
            if enable_signature:
                buffer = self.apply_digital_signature(buffer)
            
            # Get PDF content
            buffer.seek(0)
            pdf_content = buffer.getvalue()
            buffer.close()
            
            return pdf_content
            
        except Exception as e:
            logger.error(f"Error generating analytics PDF: {str(e)}")
            return self._create_error_pdf(f"Error generating PDF: {str(e)}")
    
    def _create_document(self, buffer: BytesIO, report_type: str, date_range: Dict[str, Any]) -> BaseDocTemplate:
        """Create PDF document with custom page template"""
        doc = BaseDocTemplate(
            buffer,
            pagesize=self.page_size,
            rightMargin=self.margin,
            leftMargin=self.margin,
            topMargin=self.margin + 1*cm,  # Extra space for header
            bottomMargin=self.margin + 1*cm,  # Extra space for footer
            title=f"{report_type.replace('_', ' ').title()} Report",
            author=self.company_info['name'],
            subject=f"Analytics Report for {date_range.get('start', '')} to {date_range.get('end', '')}"
        )
        
        # Create frame for content
        frame = Frame(
            self.margin, self.margin,
            self.page_size[0] - 2*self.margin,
            self.page_size[1] - 2*self.margin - 2*cm,
            id='normal'
        )
        
        # Create page template with header and footer
        template = PageTemplate(
            id='main',
            frames=frame,
            onPage=self._create_page_header_footer
        )
        
        doc.addPageTemplates([template])
        
        return doc
    
    def _create_page_header_footer(self, canvas_obj, doc):
        """Create header and footer for each page"""
        canvas_obj.saveState()
        
        # Header
        canvas_obj.setFont('Helvetica-Bold', 12)
        canvas_obj.setFillColor(self.colors['primary'])
        canvas_obj.drawString(self.margin, self.page_size[1] - self.margin, self.company_info['name'])
        
        # Header line
        canvas_obj.setStrokeColor(self.colors['secondary'])
        canvas_obj.setLineWidth(2)
        canvas_obj.line(self.margin, self.page_size[1] - self.margin - 0.5*cm, 
                       self.page_size[0] - self.margin, self.page_size[1] - self.margin - 0.5*cm)
        
        # Footer
        canvas_obj.setFont('Helvetica', 8)
        canvas_obj.setFillColor(self.colors['dark_gray'])
        
        # Company info in footer
        footer_text = f"{self.company_info['address']} | {self.company_info['phone']} | {self.company_info['email']}"
        canvas_obj.drawCentredText(self.page_size[0]/2, self.margin - 0.5*cm, footer_text)
        
        # Page number
        canvas_obj.drawRightString(self.page_size[0] - self.margin, self.margin - 0.5*cm, 
                                  f"Page {doc.page}")
        
        # Generation timestamp
        canvas_obj.drawString(self.margin, self.margin - 0.5*cm, 
                             f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        
        canvas_obj.restoreState()
    
    def _create_title_page(self, report_type: str, date_range: Dict[str, Any]) -> List:
        """Create title page content"""
        story = []
        
        # Main title
        title = report_type.replace('_', ' ').title() + " Report"
        story.append(Paragraph(title, self.styles['CustomTitle']))
        story.append(Spacer(1, 1*cm))
        
        # Date range
        date_text = f"Period: {date_range.get('start', 'N/A')} to {date_range.get('end', 'N/A')}"
        story.append(Paragraph(date_text, self.styles['CustomSubtitle']))
        story.append(Spacer(1, 2*cm))
        
        # Company logo placeholder (if available)
        # story.append(self._create_logo_section())
        
        # Report summary box
        summary_data = [
            ['Report Type', title],
            ['Date Range', date_text],
            ['Generated On', datetime.now().strftime('%Y-%m-%d %H:%M:%S')],
            ['Generated By', self.company_info['name']]
        ]
        
        summary_table = Table(summary_data, colWidths=[4*cm, 8*cm])
        summary_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, -1), self.colors['light_gray']),
            ('TEXTCOLOR', (0, 0), (-1, -1), self.colors['dark_gray']),
            ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
            ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
            ('FONTNAME', (1, 0), (1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 0), (-1, -1), 10),
            ('GRID', (0, 0), (-1, -1), 1, self.colors['secondary']),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('LEFTPADDING', (0, 0), (-1, -1), 12),
            ('RIGHTPADDING', (0, 0), (-1, -1), 12),
            ('TOPPADDING', (0, 0), (-1, -1), 8),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 8),
        ]))
        
        story.append(summary_table)
        story.append(PageBreak())
        
        return story
    
    def _create_executive_summary(self, data: Dict[str, Any]) -> List:
        """Create executive summary section"""
        story = []
        
        story.append(Paragraph("Executive Summary", self.styles['CustomSubtitle']))
        story.append(Spacer(1, 0.5*cm))
        
        # Extract key insights from data
        summary = data.get('summary', {})
        
        summary_text = self._generate_summary_text(summary)
        story.append(Paragraph(summary_text, self.styles['CustomBody']))
        story.append(Spacer(1, 1*cm))
        
        return story
    
    def _generate_summary_text(self, summary: Dict[str, Any]) -> str:
        """Generate executive summary text based on data"""
        text_parts = []
        
        if 'total_loans' in summary:
            text_parts.append(f"This report covers {summary['total_loans']} loans")
        
        if 'total_amount' in summary:
            amount = float(summary['total_amount'])
            text_parts.append(f"with a total value of KES {amount:,.2f}")
        
        if 'delinquent_count' in summary:
            delinquent = summary['delinquent_count']
            text_parts.append(f"Of these, {delinquent} loans are currently delinquent")
        
        if text_parts:
            return ". ".join(text_parts) + "."
        else:
            return "This report provides comprehensive analytics and insights into the loan portfolio performance."
    
    def _create_kpi_section(self, data: Dict[str, Any]) -> List:
        """Create KPI (Key Performance Indicators) section"""
        story = []
        
        story.append(Paragraph("Key Performance Indicators", self.styles['CustomSubtitle']))
        story.append(Spacer(1, 0.5*cm))
        
        summary = data.get('summary', {})
        
        # Create KPI cards in a table format
        kpi_data = self._extract_kpis(summary)
        
        if kpi_data:
            # Create 2x2 or 2x3 grid of KPIs
            rows = []
            for i in range(0, len(kpi_data), 2):
                row_kpis = kpi_data[i:i+2]
                row = []
                for kpi in row_kpis:
                    kpi_cell = [
                        Paragraph(kpi['value'], self.styles['KPIValue']),
                        Paragraph(kpi['label'], self.styles['KPILabel'])
                    ]
                    row.append(kpi_cell)
                
                # Pad row if needed
                while len(row) < 2:
                    row.append(['', ''])
                
                rows.append(row)
            
            # Flatten the nested structure for Table
            table_data = []
            for row in rows:
                value_row = [cell[0] if isinstance(cell, list) else cell for cell in row]
                label_row = [cell[1] if isinstance(cell, list) else cell for cell in row]
                table_data.extend([value_row, label_row])
            
            kpi_table = Table(table_data, colWidths=[8*cm, 8*cm])
            kpi_table.setStyle(TableStyle([
                ('BACKGROUND', (0, 0), (-1, -1), self.colors['light_gray']),
                ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                ('GRID', (0, 0), (-1, -1), 1, self.colors['secondary']),
                ('LEFTPADDING', (0, 0), (-1, -1), 12),
                ('RIGHTPADDING', (0, 0), (-1, -1), 12),
                ('TOPPADDING', (0, 0), (-1, -1), 12),
                ('BOTTOMPADDING', (0, 0), (-1, -1), 12),
            ]))
            
            story.append(kpi_table)
        
        story.append(Spacer(1, 1*cm))
        return story
    
    def _extract_kpis(self, summary: Dict[str, Any]) -> List[Dict[str, str]]:
        """Extract KPIs from summary data"""
        kpis = []
        
        if 'total_loans' in summary:
            kpis.append({
                'value': str(summary['total_loans']),
                'label': 'Total Loans'
            })
        
        if 'total_amount' in summary:
            amount = float(summary['total_amount'])
            kpis.append({
                'value': f"KES {amount:,.0f}",
                'label': 'Total Amount'
            })
        
        if 'delinquent_count' in summary:
            kpis.append({
                'value': str(summary['delinquent_count']),
                'label': 'Delinquent Loans'
            })
        
        if 'collection_rate' in summary:
            rate = float(summary['collection_rate'])
            kpis.append({
                'value': f"{rate:.1f}%",
                'label': 'Collection Rate'
            })
        
        return kpis
    
    def _create_charts_section(self, report_type: str, data: Dict[str, Any], 
                             charts_config: Dict[str, Any]) -> List:
        """Create charts section with embedded analytics"""
        story = []
        
        story.append(Paragraph("Analytics & Visualizations", self.styles['CustomSubtitle']))
        story.append(Spacer(1, 0.5*cm))
        
        # Generate charts based on report type
        if report_type == 'loans_due':
            story.extend(self._create_loans_due_charts(data))
        elif report_type == 'delinquent_loans':
            story.extend(self._create_delinquent_charts(data))
        elif report_type == 'loans_in_arrears':
            story.extend(self._create_arrears_charts(data))
        elif report_type == 'processing_fees':
            story.extend(self._create_processing_fees_charts(data))
        elif report_type == 'interest_income':
            story.extend(self._create_interest_charts(data))
        elif report_type == 'registration_fees':
            story.extend(self._create_registration_charts(data))
        else:
            story.extend(self._create_dashboard_charts(data))
        
        return story
    
    def _create_enhanced_charts_section(self, report_type: str, data: Dict[str, Any], 
                                      charts_config: Dict[str, Any]) -> List:
        """Create enhanced charts section with complex layouts"""
        story = []
        
        story.append(Paragraph("Analytics & Visualizations", self.styles['CustomSubtitle']))
        story.append(Spacer(1, 0.5*cm))
        
        # Generate multiple charts with complex layouts
        if report_type == 'loans_due':
            story.extend(self._create_enhanced_loans_due_charts(data))
        elif report_type == 'delinquent_loans':
            story.extend(self._create_enhanced_delinquent_charts(data))
        elif report_type == 'loans_in_arrears':
            story.extend(self._create_enhanced_arrears_charts(data))
        elif report_type == 'processing_fees':
            story.extend(self._create_enhanced_processing_fees_charts(data))
        elif report_type == 'interest_income':
            story.extend(self._create_enhanced_interest_charts(data))
        elif report_type == 'registration_fees':
            story.extend(self._create_enhanced_registration_charts(data))
        else:
            story.extend(self._create_enhanced_dashboard_charts(data))
        
        return story
    
    def _create_enhanced_loans_due_charts(self, data: Dict[str, Any]) -> List:
        """Create enhanced charts for loans due report with complex layouts"""
        story = []
        
        summary = data.get('summary', {})
        
        # Complex layout: Text analysis with embedded chart
        analysis_text = f"""
        <b>Loans Due Analysis:</b><br/>
        The current portfolio shows {summary.get('total_loans', 0)} loans with varying due dates.
        Immediate attention is required for {summary.get('today_due_count', 0)} loans due today,
        representing KES {float(summary.get('today_due_amount', 0)):,.2f} in outstanding amounts.
        
        <b>Risk Assessment:</b><br/>
        • High Priority: {summary.get('today_due_count', 0)} loans due today<br/>
        • Medium Priority: {summary.get('tomorrow_due_count', 0)} loans due tomorrow<br/>
        • Low Priority: {summary.get('week_due_count', 0)} loans due this week<br/>
        """
        
        # Create urgency chart
        urgency_data = {
            'labels': ['Due Today', 'Due Tomorrow', 'Due This Week', 'Due Later'],
            'values': [
                float(summary.get('today_due_amount', 0)),
                float(summary.get('tomorrow_due_amount', 0)),
                float(summary.get('week_due_amount', 0)),
                float(summary.get('later_due_amount', 0))
            ],
            'title': 'Loan Amounts Due by Urgency',
            'format_currency': True
        }
        
        # Create complex layout section
        complex_content = {
            'text_content': analysis_text,
            'chart_data': urgency_data,
            'chart_type': 'bar'
        }
        
        story.extend(self.create_complex_layout_section("Due Amounts Analysis", complex_content))
        
        # Add additional standalone charts
        count_data = {
            'labels': ['Due Today', 'Due Tomorrow', 'Due This Week', 'Due Later'],
            'values': [
                summary.get('today_due_count', 0),
                summary.get('tomorrow_due_count', 0),
                summary.get('week_due_count', 0),
                summary.get('later_due_count', 0)
            ],
            'title': 'Distribution of Loans Due by Count'
        }
        
        chart_image = self.chart_service.generate_chart_for_pdf('pie', count_data)
        if chart_image:
            story.append(Paragraph("Loan Count Distribution", self.styles['CustomBody']))
            story.append(self._embed_chart_image(chart_image))
            story.append(Spacer(1, 1*cm))
        
        return story
    
    def _create_enhanced_delinquent_charts(self, data: Dict[str, Any]) -> List:
        """Create enhanced charts for delinquent loans with risk analysis"""
        story = []
        
        # Risk matrix analysis
        if 'aging_buckets' in data:
            aging_analysis = f"""
            <b>Delinquency Aging Analysis:</b><br/>
            The portfolio shows varying levels of delinquency across different time periods.
            Early intervention is crucial for loans in the 1-30 days overdue category to prevent
            further deterioration.
            
            <b>Collection Strategy:</b><br/>
            • Immediate contact for 1-30 days overdue<br/>
            • Formal notices for 31-60 days overdue<br/>
            • Legal action consideration for 90+ days overdue<br/>
            """
            
            aging_data = {
                'labels': list(data['aging_buckets'].keys()),
                'values': list(data['aging_buckets'].values()),
                'title': 'Delinquent Loans Aging Analysis',
                'format_currency': True
            }
            
            complex_content = {
                'text_content': aging_analysis,
                'chart_data': aging_data,
                'chart_type': 'bar'
            }
            
            story.extend(self.create_complex_layout_section("Aging Analysis", complex_content))
        
        return story
    
    def _create_enhanced_arrears_charts(self, data: Dict[str, Any]) -> List:
        """Create enhanced charts for arrears with recovery analysis"""
        story = []
        
        # Recovery strategy analysis
        recovery_text = f"""
        <b>Arrears Recovery Strategy:</b><br/>
        Current arrears portfolio requires immediate attention with structured recovery plans.
        Focus should be on high-value, low-risk accounts for maximum recovery efficiency.
        
        <b>Recovery Priorities:</b><br/>
        • High-value accounts with good payment history<br/>
        • Recent arrears with minimal overdue periods<br/>
        • Accounts with collateral or guarantors<br/>
        """
        
        # Create amount distribution chart
        if 'amount_ranges' in data:
            amount_data = {
                'labels': list(data['amount_ranges'].keys()),
                'values': list(data['amount_ranges'].values()),
                'title': 'Arrears Amount Distribution'
            }
            
            complex_content = {
                'text_content': recovery_text,
                'chart_data': amount_data,
                'chart_type': 'bar'
            }
            
            story.extend(self.create_complex_layout_section("Recovery Analysis", complex_content))
        
        return story
    
    def _create_enhanced_processing_fees_charts(self, data: Dict[str, Any]) -> List:
        """Create enhanced charts for processing fees with revenue analysis"""
        story = []
        
        # Revenue analysis
        revenue_text = f"""
        <b>Processing Fee Revenue Analysis:</b><br/>
        Processing fees represent a significant revenue stream that requires careful monitoring
        and optimization. Trends show seasonal variations that can inform business planning.
        
        <b>Revenue Optimization:</b><br/>
        • Monitor fee collection rates<br/>
        • Analyze product-wise performance<br/>
        • Identify growth opportunities<br/>
        """
        
        if 'monthly_revenue' in data:
            revenue_data = {
                'dates': data['monthly_revenue'].get('months', []),
                'series': [{
                    'name': 'Processing Fee Revenue',
                    'values': data['monthly_revenue'].get('amounts', [])
                }],
                'title': 'Processing Fee Revenue Trend',
                'format_currency': True
            }
            
            complex_content = {
                'text_content': revenue_text,
                'chart_data': revenue_data,
                'chart_type': 'line'
            }
            
            story.extend(self.create_complex_layout_section("Revenue Analysis", complex_content))
        
        return story
    
    def _create_enhanced_interest_charts(self, data: Dict[str, Any]) -> List:
        """Create enhanced charts for interest income"""
        story = []
        
        if 'product_performance' in data:
            product_data = {
                'labels': list(data['product_performance'].keys()),
                'values': list(data['product_performance'].values()),
                'title': 'Interest Income by Product Type',
                'format_currency': True
            }
            
            chart_image = self.chart_service.generate_chart_for_pdf('bar', product_data)
            if chart_image:
                story.append(Paragraph("Interest Income by Product Type", self.styles['CustomBody']))
                story.append(self._embed_chart_image(chart_image))
                story.append(Spacer(1, 1*cm))
        
        return story
    
    def _create_enhanced_registration_charts(self, data: Dict[str, Any]) -> List:
        """Create enhanced charts for registration fees"""
        story = []
        
        if 'product_breakdown' in data:
            product_data = {
                'labels': list(data['product_breakdown'].keys()),
                'values': list(data['product_breakdown'].values()),
                'title': 'Registration Fees by Product Type',
                'format_currency': True
            }
            
            chart_image = self.chart_service.generate_chart_for_pdf('pie', product_data)
            if chart_image:
                story.append(Paragraph("Registration Fees by Product Type", self.styles['CustomBody']))
                story.append(self._embed_chart_image(chart_image))
                story.append(Spacer(1, 1*cm))
        
        return story
    
    def _create_enhanced_dashboard_charts(self, data: Dict[str, Any]) -> List:
        """Create enhanced charts for dashboard overview"""
        story = []
        
        # Portfolio overview with analysis
        portfolio_text = f"""
        <b>Portfolio Overview:</b><br/>
        The current portfolio demonstrates balanced performance across different loan categories.
        Active monitoring of delinquent accounts ensures healthy portfolio management.
        
        <b>Key Insights:</b><br/>
        • Portfolio diversification across loan types<br/>
        • Proactive delinquency management<br/>
        • Consistent loan completion rates<br/>
        """
        
        portfolio_data = {
            'labels': ['Active Loans', 'Delinquent', 'Completed'],
            'values': [
                data.get('loans_due', {}).get('summary', {}).get('total_active', 0),
                data.get('delinquent', {}).get('summary', {}).get('total_delinquent', 0),
                data.get('loans_due', {}).get('summary', {}).get('total_completed', 0)
            ],
            'title': 'Portfolio Overview'
        }
        
        complex_content = {
            'text_content': portfolio_text,
            'chart_data': portfolio_data,
            'chart_type': 'pie'
        }
        
        story.extend(self.create_complex_layout_section("Portfolio Overview", complex_content))
        
        return story
    
    def _create_loans_due_charts(self, data: Dict[str, Any]) -> List:
        """Create charts specific to loans due report"""
        story = []
        
        summary = data.get('summary', {})
        
        # Due amounts by urgency chart
        urgency_data = {
            'labels': ['Due Today', 'Due Tomorrow', 'Due This Week', 'Due Later'],
            'values': [
                float(summary.get('today_due_amount', 0)),
                float(summary.get('tomorrow_due_amount', 0)),
                float(summary.get('week_due_amount', 0)),
                float(summary.get('later_due_amount', 0))
            ],
            'title': 'Loan Amounts Due by Urgency',
            'format_currency': True
        }
        
        chart_image = self.chart_service.generate_chart_for_pdf('bar', urgency_data)
        if chart_image:
            story.append(Paragraph("Loan Amounts Due by Urgency", self.styles['CustomBody']))
            story.append(self._embed_chart_image(chart_image))
            story.append(Spacer(1, 0.5*cm))
        
        # Count distribution pie chart
        count_data = {
            'labels': ['Due Today', 'Due Tomorrow', 'Due This Week', 'Due Later'],
            'values': [
                summary.get('today_due_count', 0),
                summary.get('tomorrow_due_count', 0),
                summary.get('week_due_count', 0),
                summary.get('later_due_count', 0)
            ],
            'title': 'Distribution of Loans Due by Count'
        }
        
        chart_image = self.chart_service.generate_chart_for_pdf('pie', count_data)
        if chart_image:
            story.append(Paragraph("Distribution of Loans Due by Count", self.styles['CustomBody']))
            story.append(self._embed_chart_image(chart_image))
            story.append(Spacer(1, 1*cm))
        
        return story
    
    def _create_delinquent_charts(self, data: Dict[str, Any]) -> List:
        """Create charts specific to delinquent loans report"""
        story = []
        
        # Aging analysis chart
        if 'aging_buckets' in data:
            aging_data = {
                'labels': list(data['aging_buckets'].keys()),
                'values': list(data['aging_buckets'].values()),
                'title': 'Delinquent Loans Aging Analysis',
                'format_currency': True
            }
            
            chart_image = self.chart_service.generate_chart_for_pdf('bar', aging_data)
            if chart_image:
                story.append(Paragraph("Delinquent Loans Aging Analysis", self.styles['CustomBody']))
                story.append(self._embed_chart_image(chart_image))
                story.append(Spacer(1, 1*cm))
        
        return story
    
    def _create_arrears_charts(self, data: Dict[str, Any]) -> List:
        """Create charts specific to arrears report"""
        story = []
        
        # Amount distribution chart
        if 'amount_ranges' in data:
            amount_data = {
                'labels': list(data['amount_ranges'].keys()),
                'values': list(data['amount_ranges'].values()),
                'title': 'Arrears Amount Distribution'
            }
            
            chart_image = self.chart_service.generate_chart_for_pdf('bar', amount_data)
            if chart_image:
                story.append(Paragraph("Arrears Amount Distribution", self.styles['CustomBody']))
                story.append(self._embed_chart_image(chart_image))
                story.append(Spacer(1, 1*cm))
        
        return story
    
    def _create_processing_fees_charts(self, data: Dict[str, Any]) -> List:
        """Create charts specific to processing fees report"""
        story = []
        
        # Revenue trend chart
        if 'monthly_revenue' in data:
            revenue_data = {
                'dates': data['monthly_revenue'].get('months', []),
                'series': [{
                    'name': 'Processing Fee Revenue',
                    'values': data['monthly_revenue'].get('amounts', [])
                }],
                'title': 'Processing Fee Revenue Trend',
                'format_currency': True
            }
            
            chart_image = self.chart_service.generate_chart_for_pdf('line', revenue_data)
            if chart_image:
                story.append(Paragraph("Processing Fee Revenue Trend", self.styles['CustomBody']))
                story.append(self._embed_chart_image(chart_image))
                story.append(Spacer(1, 1*cm))
        
        return story
    
    def _create_interest_charts(self, data: Dict[str, Any]) -> List:
        """Create charts specific to interest income report"""
        story = []
        
        # Product performance chart
        if 'product_performance' in data:
            product_data = {
                'labels': list(data['product_performance'].keys()),
                'values': list(data['product_performance'].values()),
                'title': 'Interest Income by Product Type',
                'format_currency': True
            }
            
            chart_image = self.chart_service.generate_chart_for_pdf('bar', product_data)
            if chart_image:
                story.append(Paragraph("Interest Income by Product Type", self.styles['CustomBody']))
                story.append(self._embed_chart_image(chart_image))
                story.append(Spacer(1, 1*cm))
        
        return story
    
    def _create_registration_charts(self, data: Dict[str, Any]) -> List:
        """Create charts specific to registration fees report"""
        story = []
        
        # Product breakdown chart
        if 'product_breakdown' in data:
            product_data = {
                'labels': list(data['product_breakdown'].keys()),
                'values': list(data['product_breakdown'].values()),
                'title': 'Registration Fees by Product Type',
                'format_currency': True
            }
            
            chart_image = self.chart_service.generate_chart_for_pdf('pie', product_data)
            if chart_image:
                story.append(Paragraph("Registration Fees by Product Type", self.styles['CustomBody']))
                story.append(self._embed_chart_image(chart_image))
                story.append(Spacer(1, 1*cm))
        
        return story
    
    def _create_dashboard_charts(self, data: Dict[str, Any]) -> List:
        """Create charts for dashboard overview"""
        story = []
        
        # Portfolio overview
        portfolio_data = {
            'labels': ['Active Loans', 'Delinquent', 'Completed'],
            'values': [
                data.get('loans_due', {}).get('summary', {}).get('total_active', 0),
                data.get('delinquent', {}).get('summary', {}).get('total_delinquent', 0),
                data.get('loans_due', {}).get('summary', {}).get('total_completed', 0)
            ],
            'title': 'Portfolio Overview'
        }
        
        chart_image = self.chart_service.generate_chart_for_pdf('pie', portfolio_data)
        if chart_image:
            story.append(Paragraph("Portfolio Overview", self.styles['CustomBody']))
            story.append(self._embed_chart_image(chart_image))
            story.append(Spacer(1, 1*cm))
        
        return story
    
    def _embed_chart_image(self, chart_image_bytes: bytes) -> Image:
        """Embed chart image in PDF"""
        try:
            # Create temporary file for the image
            with tempfile.NamedTemporaryFile(delete=False, suffix='.png') as temp_file:
                temp_file.write(chart_image_bytes)
                temp_file.flush()
                
                # Create ReportLab Image
                img = Image(temp_file.name, width=self.chart_width, height=self.chart_height)
                
                # Clean up temporary file
                os.unlink(temp_file.name)
                
                return img
                
        except Exception as e:
            logger.error(f"Error embedding chart image: {str(e)}")
            # Return placeholder text if image embedding fails
            return Paragraph("Chart could not be generated", self.styles['CustomBody'])
    
    def _create_data_tables(self, report_type: str, data: Dict[str, Any]) -> List:
        """Create detailed data tables section"""
        story = []
        
        story.append(PageBreak())
        story.append(Paragraph("Detailed Data", self.styles['CustomSubtitle']))
        story.append(Spacer(1, 0.5*cm))
        
        # Create tables based on report type
        if 'loans' in data and data['loans']:
            story.extend(self._create_loans_table(data['loans']))
        
        return story
    
    def _create_loans_table(self, loans_data: List[Dict[str, Any]]) -> List:
        """Create detailed loans data table"""
        story = []
        
        if not loans_data:
            story.append(Paragraph("No loan data available.", self.styles['CustomBody']))
            return story
        
        # Table headers
        headers = ['Loan ID', 'Borrower', 'Amount', 'Due Date', 'Status']
        
        # Table data
        table_data = [headers]
        
        for loan in loans_data[:20]:  # Limit to first 20 loans
            row = [
                str(loan.get('id', 'N/A')),
                str(loan.get('borrower_name', 'N/A')),
                f"KES {float(loan.get('amount', 0)):,.2f}",
                str(loan.get('due_date', 'N/A')),
                str(loan.get('status', 'N/A'))
            ]
            table_data.append(row)
        
        # Create table
        loans_table = Table(table_data, colWidths=[2*cm, 4*cm, 3*cm, 3*cm, 2*cm])
        loans_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), self.colors['secondary']),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
            ('FONTSIZE', (0, 0), (-1, 0), 10),
            ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
            ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 1), (-1, -1), 8),
            ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, self.colors['light_gray']]),
        ]))
        
        story.append(loans_table)
        story.append(Spacer(1, 1*cm))
        
        return story
    
    def _create_appendix(self) -> List:
        """Create appendix with methodology and notes"""
        story = []
        
        story.append(PageBreak())
        story.append(Paragraph("Appendix", self.styles['CustomSubtitle']))
        story.append(Spacer(1, 0.5*cm))
        
        # Methodology section
        story.append(Paragraph("Methodology", self.styles['CustomBody']))
        methodology_text = """
        This report was generated using the Loan Management System's analytics engine. 
        Data is extracted from the operational database and processed to provide accurate 
        insights into loan portfolio performance. All calculations follow standard 
        financial reporting practices.
        """
        story.append(Paragraph(methodology_text, self.styles['CustomBody']))
        story.append(Spacer(1, 0.5*cm))
        
        # Notes section
        story.append(Paragraph("Notes", self.styles['CustomBody']))
        notes_text = """
        • All amounts are displayed in Kenya Shillings (KES)
        • Delinquent loans are those past their due date
        • Collection rates are calculated based on expected vs actual payments
        • Charts and graphs are generated in real-time based on current data
        """
        story.append(Paragraph(notes_text, self.styles['CustomBody']))
        
        return story
    
    def _create_error_pdf(self, error_message: str) -> bytes:
        """Create error PDF when generation fails"""
        try:
            buffer = BytesIO()
            doc = SimpleDocTemplate(buffer, pagesize=self.page_size)
            
            story = [
                Paragraph("Report Generation Error", self.styles['CustomTitle']),
                Spacer(1, 1*cm),
                Paragraph(f"An error occurred while generating the report: {error_message}", 
                         self.styles['CustomBody']),
                Spacer(1, 1*cm),
                Paragraph("Please try again or contact system administrator.", 
                         self.styles['CustomBody'])
            ]
            
            doc.build(story)
            buffer.seek(0)
            return buffer.getvalue()
            
        except Exception as e:
            logger.error(f"Error creating error PDF: {str(e)}")
            return b"PDF generation failed"
    
    def generate_filename(self, report_type: str, date_range: Dict[str, Any]) -> str:
        """Generate meaningful filename for the PDF"""
        try:
            report_name = report_type.replace('_', '-')
            start_date = date_range.get('start', 'unknown')
            end_date = date_range.get('end', 'unknown')
            timestamp = datetime.now().strftime('%Y%m%d-%H%M%S')
            
            return f"{report_name}-report-{start_date}-to-{end_date}-{timestamp}.pdf"
            
        except Exception as e:
            logger.error(f"Error generating filename: {str(e)}")
            return f"report-{datetime.now().strftime('%Y%m%d-%H%M%S')}.pdf"    
def generate_audit_report(self, data: List[Dict[str, Any]], title: str) -> bytes:
        """Generate audit report PDF"""
        try:
            buffer = BytesIO()
            doc = SimpleDocTemplate(buffer, pagesize=self.page_size)
            
            story = []
            
            # Title page
            story.append(Paragraph(title, self.styles['CustomTitle']))
            story.append(Spacer(1, 0.5*cm))
            story.append(Paragraph(f"Generated on: {datetime.now().strftime('%B %d, %Y at %I:%M %p')}", 
                                 self.styles['CustomBody']))
            story.append(Spacer(1, 1*cm))
            
            # Summary
            story.append(Paragraph("Summary", self.styles['CustomSubtitle']))
            story.append(Paragraph(f"Total audit entries: {len(data)}", self.styles['CustomBody']))
            story.append(Spacer(1, 0.5*cm))
            
            # Data table
            if data:
                story.append(Paragraph("Audit Trail Details", self.styles['CustomSubtitle']))
                story.append(Spacer(1, 0.3*cm))
                
                # Table headers
                headers = ['Timestamp', 'User', 'Event Type', 'Action', 'Module', 'Description']
                
                # Prepare table data
                table_data = [headers]
                for entry in data[:50]:  # Limit to first 50 entries
                    row = [
                        entry.get('timestamp', 'N/A'),
                        entry.get('user', 'N/A'),
                        entry.get('event_type', 'N/A'),
                        entry.get('action', 'N/A'),
                        entry.get('module', 'N/A'),
                        entry.get('description', 'N/A')[:50] + '...' if len(entry.get('description', '')) > 50 else entry.get('description', 'N/A')
                    ]
                    table_data.append(row)
                
                # Create table
                audit_table = Table(table_data, colWidths=[3*cm, 2.5*cm, 2*cm, 2.5*cm, 2*cm, 4*cm])
                audit_table.setStyle(TableStyle([
                    ('BACKGROUND', (0, 0), (-1, 0), self.colors['primary']),
                    ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
                    ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
                    ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
                    ('FONTSIZE', (0, 0), (-1, 0), 9),
                    ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
                    ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
                    ('GRID', (0, 0), (-1, -1), 1, colors.black),
                    ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),
                    ('FONTSIZE', (0, 1), (-1, -1), 8),
                    ('VALIGN', (0, 0), (-1, -1), 'TOP'),
                ]))
                
                story.append(audit_table)
                
                if len(data) > 50:
                    story.append(Spacer(1, 0.5*cm))
                    story.append(Paragraph(f"Note: Showing first 50 of {len(data)} total entries. Full data available in CSV export.", 
                                         self.styles['CustomBody']))
            else:
                story.append(Paragraph("No audit data available.", self.styles['CustomBody']))
            
            # Footer
            story.append(Spacer(1, 1*cm))
            story.append(Paragraph("This report contains sensitive audit information and should be handled according to security policies.", 
                                 self.styles['CustomBody']))
            
            doc.build(story)
            buffer.seek(0)
            return buffer.getvalue()
            
        except Exception as e:
            logger.error(f"Error generating audit PDF: {str(e)}")
            return self._create_error_pdf(f"Error generating audit report: {str(e)}")