"""
PDF report generator for KPI Analysis
Creates professional PDF reports with charts and analysis
"""

import os
from typing import List, Dict, Any, Optional
from datetime import datetime
import base64
from io import BytesIO
import pandas as pd

# Optional imports for PDF generation
try:
    import matplotlib.pyplot as plt
    import matplotlib.patches as mpatches
    import seaborn as sns
    import warnings
    # Suppress matplotlib warnings
    warnings.filterwarnings('ignore', category=UserWarning, module='matplotlib')
    MATPLOTLIB_AVAILABLE = True
except ImportError:
    MATPLOTLIB_AVAILABLE = False

try:
    from reportlab.lib.pagesizes import letter, A4
    from reportlab.lib import colors
    from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
    from reportlab.lib.units import inch
    from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Image, PageBreak
    from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
    from reportlab.pdfgen import canvas
    from reportlab.platypus.frames import Frame
    from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
    REPORTLAB_AVAILABLE = True
except ImportError:
    REPORTLAB_AVAILABLE = False
    # Create dummy classes for when ReportLab is not available
    colors = type('colors', (), {
        'darkblue': None, 'whitesmoke': None, 'darkgreen': None, 'red': None,
        'beige': None, 'black': None, 'blue': None, 'lightgrey': None, 'darkgreen': None,
        'lightgreen': None, 'grey': None, 'lightblue': None
    })()
    
    TA_CENTER = 1
    TA_LEFT = 0
    TA_RIGHT = 2
    
    # Dummy classes and functions
    letter = A4 = (595, 842)
    inch = 72
    
    class SimpleDocTemplate:
        def __init__(self, *args, **kwargs): pass
        def build(self, *args): pass
    
    class ParagraphStyle:
        def __init__(self, *args, **kwargs): pass
    
    class Paragraph:
        def __init__(self, *args, **kwargs): pass
    
    class Spacer:
        def __init__(self, *args, **kwargs): pass
    
    class Table:
        def __init__(self, *args, **kwargs): pass
        def setStyle(self, *args): pass
    
    class TableStyle:
        pass
    
    class Image:
        def __init__(self, *args, **kwargs): pass
    
    class PageBreak:
        pass
    
    def getSampleStyleSheet():
        return type('styles', (), {'Normal': None, 'Heading1': None, 'Heading2': None, 'Heading3': None})()
    
    # Create a dummy styles instance
    styles = getSampleStyleSheet()

import logging

from ..models.kpi_models import KPIFile, AnalysisResult
from config.settings import settings

logger = logging.getLogger(__name__)

class PDFGenerator:
    """Professional PDF report generator for KPI analysis"""
    
    def __init__(self):
        self.setup_styles()
        
    def setup_styles(self):
        """Setup document styles"""
        if REPORTLAB_AVAILABLE:
            self.styles = getSampleStyleSheet()
            
            # Custom styles
            self.styles.add(ParagraphStyle(
                name='CustomTitle',
                parent=self.styles['Heading1'],
                fontSize=20,
                spaceAfter=20,
                alignment=TA_CENTER,
                textColor=colors.darkblue
            ))
            
            self.styles.add(ParagraphStyle(
                name='CustomHeading2',
                parent=self.styles['Heading2'],
                fontSize=14,
                spaceAfter=12,
                textColor=colors.darkblue
            ))
            
            self.styles.add(ParagraphStyle(
                name='CustomHeading3',
                parent=self.styles['Heading3'],
                fontSize=12,
                spaceAfter=10,
                textColor=colors.darkblue
            ))
            
            self.styles.add(ParagraphStyle(
                name='CustomNormal',
                parent=self.styles['Normal'],
                fontSize=10,
                spaceAfter=6
            ))
            
            self.styles.add(ParagraphStyle(
                name='Highlight',
                parent=self.styles['Normal'],
                fontSize=11,
                textColor=colors.darkgreen,
                spaceAfter=8
            ))
        else:
            self.styles = None
    
    async def generate_report(self, kpi_file: KPIFile, analysis_result: AnalysisResult) -> str:
        """Generate comprehensive PDF report"""
        if not REPORTLAB_AVAILABLE:
            logger.warning("ReportLab not available - skipping PDF generation")
            return ""
        
        try:
            # Create output directory
            os.makedirs(settings.reports_directory, exist_ok=True)
            
            # Generate filename - sanitize name to remove invalid characters
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            # Remove or replace invalid filename characters
            safe_name = kpi_file.summary.name.replace(' ', '_').replace('/', '_').replace('\\', '_').replace(':', '_')
            # Limit filename length
            safe_name = safe_name[:50] if len(safe_name) > 50 else safe_name
            filename = f"kpi_report_{safe_name}_{timestamp}.pdf"
            report_path = os.path.join(settings.reports_directory, filename)
            
            # Create PDF document
            doc = SimpleDocTemplate(
                report_path,
                pagesize=A4,
                rightMargin=72,
                leftMargin=72,
                topMargin=72,
                bottomMargin=18
            )
            
            # Build PDF content
            story = []
            
            # Title page
            self._add_title_page(story, kpi_file)
            
            # Executive summary
            self._add_executive_summary(story, kpi_file, analysis_result)
            
            # Performance overview
            self._add_performance_overview(story, kpi_file, analysis_result)
            
            # Detailed analysis
            self._add_detailed_analysis(story, kpi_file, analysis_result)
            
            # Charts and visualizations
            self._add_charts_section(story, kpi_file, analysis_result)
            
            # Recommendations
            self._add_recommendations_section(story, analysis_result)
            
            # Appendix
            self._add_appendix(story, kpi_file)
            
            # Build PDF
            doc.build(story)
            
            logger.info(f"PDF report generated: {report_path}")
            return report_path
            
        except Exception as e:
            logger.error(f"Error generating PDF report: {str(e)}")
            return ""
    
    def _add_title_page(self, story: List, kpi_file: KPIFile):
        """Add title page to PDF"""
        # Title
        title = Paragraph("KPI Performance Analysis Report", self.styles['CustomTitle'])
        story.append(title)
        story.append(Spacer(1, 0.5*inch))
        
        # Subtitle
        subtitle = Paragraph(f"Performance Period: {kpi_file.summary.performance_period}", 
                           self.styles['CustomHeading2'])
        story.append(subtitle)
        story.append(Spacer(1, 0.3*inch))
        
        # Employee information
        info_data = [
            ['Name:', kpi_file.summary.name],
            ['Position:', kpi_file.summary.position],
            ['Department:', kpi_file.summary.job_title],
            ['Supervisor:', f"{kpi_file.summary.supervisor_name} - {kpi_file.summary.supervisor_position}"],
            ['Report Date:', datetime.now().strftime("%B %d, %Y")]
        ]
        
        info_table = Table(info_data, colWidths=[1.5*inch, 4*inch])
        info_table.setStyle(TableStyle([
            ('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),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 6),
        ]))
        
        story.append(info_table)
        story.append(Spacer(1, 0.5*inch))
        
        # Overall score highlight (in points, not percentage)
        score_color = colors.darkgreen if kpi_file.summary.final_score >= 80 else colors.red
        score_text = f"Overall Performance Score: {kpi_file.summary.final_score:.2f} Points"
        
        score_para = Paragraph(score_text, self.styles['CustomTitle'])
        score_para.textColor = score_color
        story.append(score_para)
        
        story.append(PageBreak())
    
    def _add_executive_summary(self, story: List, kpi_file: KPIFile, analysis_result: AnalysisResult):
        """Add executive summary section"""
        # Section header
        story.append(Paragraph("Executive Summary", self.styles['CustomHeading2']))
        story.append(Spacer(1, 0.2*inch))
        
        # Key metrics
        metrics_data = [
            ['Metric', 'Value', 'Status'],
            ['Overall Score', f"{kpi_file.summary.final_score:.2f} Points", 
             'Excellent' if kpi_file.summary.final_score >= 90 else 'Good' if kpi_file.summary.final_score >= 80 else 'Needs Improvement'],
            ['Achievement Rate', f"{kpi_file.achievement_rate:.1f}%", 
             'Strong' if kpi_file.achievement_rate >= 80 else 'Moderate'],
            ['Total KPIs Evaluated', str(len(kpi_file.achievements.items)), ''],
            ['KPIs Achieved', str(sum(1 for item in kpi_file.achievements.items if item.status.value == "Achieve")), ''],
            ['KPIs Not Achieved', str(sum(1 for item in kpi_file.achievements.items if item.status.value == "Not Achieve")), '']
        ]
        
        metrics_table = Table(metrics_data, colWidths=[2*inch, 1.5*inch, 1.5*inch])
        metrics_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), colors.darkblue),
            ('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)
        ]))
        
        story.append(metrics_table)
        story.append(Spacer(1, 0.3*inch))
        
        # Key insights
        story.append(Paragraph("Key Insights:", self.styles['CustomHeading3']))
        
        if analysis_result.insights:
            for insight in analysis_result.insights[:5]:  # Top 5 insights
                insight_para = Paragraph(f"• {insight}", self.styles['CustomNormal'])
                story.append(insight_para)
        else:
            story.append(Paragraph("• Analysis shows performance trends across all KPI perspectives", 
                                 self.styles['CustomNormal']))
        
        story.append(PageBreak())
    
    def _add_performance_overview(self, story: List, kpi_file: KPIFile, analysis_result: AnalysisResult):
        """Add performance overview section"""
        story.append(Paragraph("Performance Overview by Perspective", self.styles['CustomHeading2']))
        story.append(Spacer(1, 0.2*inch))
        
        # Perspective scores table
        perspective_data = [['Perspective', 'Score (%)', 'Rating', 'Target Gap']]
        
        ratings = {90: 'Excellent', 80: 'Good', 70: 'Satisfactory', 0: 'Needs Improvement'}
        
        for category, score in kpi_file.perspective_scores.items():
            rating = next((r for threshold, r in sorted(ratings.items(), reverse=True) if score >= threshold), 'Needs Improvement')
            target_gap = 80 - score  # Assuming 80% target
            
            perspective_data.append([
                category.value,
                f"{score:.1f}%",
                rating,
                f"{target_gap:+.1f}%" if target_gap != 0 else "On Target"
            ])
        
        perspective_table = Table(perspective_data, colWidths=[2.5*inch, 1.2*inch, 1.5*inch, 1.3*inch])
        perspective_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), colors.darkblue),
            ('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.lightgrey),
            ('GRID', (0, 0), (-1, -1), 1, colors.black)
        ]))
        
        story.append(perspective_table)
        story.append(Spacer(1, 0.3*inch))
        
        # Achievement status
        story.append(Paragraph("KPI Achievement Status", self.styles['CustomHeading3']))
        
        achievement_data = [['KPI Status', 'Count', 'Percentage']]
        
        total_kpis = len(kpi_file.achievements.items)
        for status in ['Achieve', 'Not Achieve', 'No Data']:
            count = sum(1 for item in kpi_file.achievements.items if item.status.value == status)
            percentage = (count / total_kpis * 100) if total_kpis > 0 else 0
            achievement_data.append([status, str(count), f"{percentage:.1f}%"])
        
        achievement_table = Table(achievement_data, colWidths=[2*inch, 1*inch, 1.5*inch])
        achievement_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), colors.darkgreen),
            ('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.lightgreen),
            ('GRID', (0, 0), (-1, -1), 1, colors.black)
        ]))
        
        story.append(achievement_table)
        story.append(PageBreak())
    
    def _add_detailed_analysis(self, story: List, kpi_file: KPIFile, analysis_result: AnalysisResult):
        """Add detailed analysis section"""
        story.append(Paragraph("Detailed Performance Analysis", self.styles['CustomHeading2']))
        story.append(Spacer(1, 0.2*inch))
        
        # Analyze each perspective
        for category, score in kpi_file.perspective_scores.items():
            story.append(Paragraph(f"{category.value} Perspective", self.styles['CustomHeading3']))
            
            # Get KPIs for this category
            category_kpis = [sheet for sheet in kpi_file.kpi_sheets if sheet.category == category]
            
            if category_kpis:
                # Create KPI performance table
                kpi_data = [['KPI Code', 'Name', 'Method', 'Average Score', 'Performance']]
                
                for kpi_sheet in category_kpis:
                    if kpi_sheet.period_data:
                        scores = [pd.score for pd in kpi_sheet.period_data if pd.score is not None]
                        if scores:
                            avg_score = sum(scores) / len(scores)
                            performance = 'Excellent' if avg_score >= 90 else 'Good' if avg_score >= 80 else 'Needs Improvement'
                            
                            # Get calculation method from unit
                            method = kpi_sheet.unit if kpi_sheet.unit else 'N/A'
                            if method == 'Percentage':
                                method = '%'
                            elif method == 'Count':
                                method = '#'
                            
                            kpi_data.append([
                                kpi_sheet.code,
                                kpi_sheet.name[:25] + '...' if len(kpi_sheet.name) > 25 else kpi_sheet.name,
                                method,
                                f"{avg_score:.1f}%",
                                performance
                            ])
                
                if len(kpi_data) > 1:  # More than just headers
                    kpi_table = Table(kpi_data, colWidths=[0.8*inch, 2.5*inch, 0.6*inch, 1*inch, 1.3*inch])
                    kpi_table.setStyle(TableStyle([
                        ('BACKGROUND', (0, 0), (-1, 0), colors.blue),
                        ('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), 9),
                        ('BOTTOMPADDING', (0, 0), (-1, 0), 8),
                        ('BACKGROUND', (0, 1), (-1, -1), colors.lightblue),
                        ('GRID', (0, 0), (-1, -1), 1, colors.black),
                        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                    ]))
                    
                    story.append(kpi_table)
                    story.append(Spacer(1, 0.2*inch))
            else:
                story.append(Paragraph("No KPIs found for this perspective", self.styles['CustomNormal']))
                story.append(Spacer(1, 0.1*inch))
        
        story.append(PageBreak())
    
    def _add_charts_section(self, story: List, kpi_file: KPIFile, analysis_result: AnalysisResult):
        """Add charts section"""
        story.append(Paragraph("Performance Charts and Visualizations", self.styles['CustomHeading2']))
        story.append(Spacer(1, 0.2*inch))
        
        charts_added = False
        
        # Create charts using matplotlib
        try:
            # Chart 1: Perspective scores bar chart
            chart1_path = self._create_perspective_chart(kpi_file)
            if chart1_path and os.path.exists(chart1_path):
                story.append(Paragraph("Performance by Perspective", self.styles['CustomHeading3']))
                img1 = Image(chart1_path, width=6*inch, height=4*inch)
                story.append(img1)
                story.append(Spacer(1, 0.3*inch))
                charts_added = True
            else:
                logger.info("Perspective chart not generated - likely no data available")
            
            # Chart 2: Achievement status pie chart
            chart2_path = self._create_achievement_chart(kpi_file)
            if chart2_path and os.path.exists(chart2_path):
                story.append(Paragraph("KPI Achievement Distribution", self.styles['CustomHeading3']))
                img2 = Image(chart2_path, width=6*inch, height=4*inch)
                story.append(img2)
                story.append(Spacer(1, 0.3*inch))
                charts_added = True
            else:
                logger.info("Achievement chart not generated - likely no data available")
            
            if not charts_added:
                story.append(Paragraph("Charts could not be generated due to insufficient data. Please ensure KPI data is properly populated in the Excel file.", self.styles['CustomNormal']))
            
        except Exception as e:
            logger.error(f"Error adding charts: {str(e)}", exc_info=True)
            story.append(Paragraph("Charts could not be generated due to an error. Please check the logs for details.", self.styles['CustomNormal']))
        
        story.append(PageBreak())
    
    def _create_perspective_chart(self, kpi_file: KPIFile) -> Optional[str]:
        """Create perspective scores chart"""
        if not MATPLOTLIB_AVAILABLE:
            logger.warning("Matplotlib not available - skipping chart generation")
            return None
            
        try:
            categories = [cat.value.replace(' & ', '\n& ') for cat in kpi_file.perspective_scores.keys()]
            scores = list(kpi_file.perspective_scores.values())
            
            # Check if we have any valid scores
            if not scores or all(score == 0 for score in scores):
                logger.warning("No valid perspective scores for chart generation")
                return None
            
            # Set style and create figure with fixed size
            plt.style.use('seaborn-v0_8')
            fig, ax = plt.subplots(figsize=(10, 5), dpi=100)
            
            colors_list = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4']
            
            # Shorten category labels and wrap text
            short_categories = []
            for cat in categories:
                if len(cat) > 20:
                    # Split long labels into multiple lines
                    words = cat.split()
                    if len(words) > 2:
                        mid = len(words) // 2
                        cat = ' '.join(words[:mid]) + '\n' + ' '.join(words[mid:])
                short_categories.append(cat)
            
            bars = ax.bar(short_categories, scores, color=colors_list[:len(categories)], alpha=0.85, edgecolor='white', linewidth=2)
            
            # Add value labels on bars
            for bar, score in zip(bars, scores):
                height = bar.get_height()
                if height > 0:  # Only add label if there's a value
                    ax.text(bar.get_x() + bar.get_width()/2., height + 2,
                           f'{score:.1f}%', ha='center', va='bottom', fontweight='bold', fontsize=11)
            
            # Add target line
            ax.axhline(y=80, color='#DC3545', linestyle='--', linewidth=2, alpha=0.8, label='Target (80%)')
            
            ax.set_ylabel('Score (%)', fontsize=13, fontweight='bold')
            ax.set_title('KPI Performance by Perspective', fontsize=15, fontweight='bold', pad=15)
            ax.set_ylim(0, max(scores) + 15 if scores else 100)
            ax.legend(loc='upper right', fontsize=10)
            ax.grid(True, alpha=0.2, axis='y')
            ax.set_axisbelow(True)
            
            # Rotate x-axis labels if needed
            plt.xticks(rotation=0, ha='center', fontsize=10)
            
            # Use tight_layout with error suppression
            try:
                plt.tight_layout()
            except:
                pass  # Ignore layout warnings
            
            # Save chart with reasonable DPI and white background
            chart_path = os.path.join(settings.reports_directory, f"perspective_chart_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png")
            plt.savefig(chart_path, dpi=150, bbox_inches='tight', pad_inches=0.3, facecolor='white', edgecolor='none')
            plt.close()
            
            logger.info(f"Perspective chart saved: {chart_path}")
            return chart_path
            
            return chart_path
            
        except Exception as e:
            logger.error(f"Error creating perspective chart: {str(e)}", exc_info=True)
            plt.close()  # Make sure to close the figure on error
            return None
    
    def _create_achievement_chart(self, kpi_file: KPIFile) -> Optional[str]:
        """Create achievement status pie chart"""
        if not MATPLOTLIB_AVAILABLE:
            logger.warning("Matplotlib not available - skipping chart generation")
            return None
            
        try:
            # Get achievement counts
            achieved = sum(1 for item in kpi_file.achievements.items if item.status.value == "Achieve")
            not_achieved = sum(1 for item in kpi_file.achievements.items if item.status.value == "Not Achieve")
            no_data = sum(1 for item in kpi_file.achievements.items if item.status.value == "No Data")
            
            total_kpis = achieved + not_achieved + no_data
            
            # Check if we have any KPIs
            if total_kpis == 0:
                logger.warning("No KPIs found for achievement chart")
                return None
            
            # Set style and create figure with fixed size
            plt.style.use('seaborn-v0_8')
            fig, ax = plt.subplots(figsize=(8, 8), dpi=100)
            
            labels = ['Achieved', 'Not Achieved', 'No Data']
            sizes = [achieved, not_achieved, no_data]
            colors_list = ['#28a745', '#dc3545', '#ffc107']
            
            # Filter out zero values
            filtered_data = [(label, size, color) for label, size, color in zip(labels, sizes, colors_list) if size > 0]
            
            if not filtered_data:
                logger.warning("All achievement values are zero")
                plt.close()
                return None
            
            filtered_labels, filtered_sizes, filtered_colors = zip(*filtered_data)
            
            # Create explode tuple - explode the first slice (usually achieved)
            explode = tuple([0.1 if i == 0 else 0 for i in range(len(filtered_sizes))])
            
            # Create pie chart
            wedges, texts, autotexts = ax.pie(filtered_sizes, explode=explode, labels=filtered_labels, 
                                             colors=filtered_colors, autopct='%1.1f%%', shadow=True, 
                                             startangle=90)
            
            # Enhance text
            for autotext in autotexts:
                autotext.set_color('white')
                autotext.set_fontweight('bold')
                autotext.set_fontsize(12)
            
            ax.set_title('KPI Achievement Status Distribution', fontsize=14, fontweight='bold', pad=20)
            
            # Use tight_layout with error suppression
            try:
                plt.tight_layout()
            except:
                pass  # Ignore layout warnings
            
            # Save chart with reasonable DPI and white background
            chart_path = os.path.join(settings.reports_directory, f"achievement_chart_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png")
            plt.savefig(chart_path, dpi=150, bbox_inches='tight', pad_inches=0.3, facecolor='white', edgecolor='none')
            plt.close()
            
            logger.info(f"Achievement chart saved: {chart_path}")
            return chart_path
            
            return chart_path
            
        except Exception as e:
            logger.error(f"Error creating achievement chart: {str(e)}", exc_info=True)
            plt.close()  # Make sure to close the figure on error
            return None
    
    def _add_recommendations_section(self, story: List, analysis_result: AnalysisResult):
        """Add recommendations section"""
        story.append(Paragraph("Recommendations for Improvement", self.styles['CustomHeading2']))
        story.append(Spacer(1, 0.2*inch))
        
        if analysis_result.recommendations:
            for i, recommendation in enumerate(analysis_result.recommendations, 1):
                story.append(Paragraph(f"{i}. {recommendation}", self.styles['CustomNormal']))
                story.append(Spacer(1, 0.1*inch))
        else:
            story.append(Paragraph("• Continue monitoring current performance levels", self.styles['CustomNormal']))
            story.append(Paragraph("• Focus on areas with scores below 80%", self.styles['CustomNormal']))
            story.append(Paragraph("• Develop action plans for underperforming KPIs", self.styles['CustomNormal']))
        
        story.append(PageBreak())
    
    def _add_appendix(self, story: List, kpi_file: KPIFile):
        """Add appendix with detailed data"""
        story.append(Paragraph("Appendix: Detailed KPI Data", self.styles['CustomHeading2']))
        story.append(Spacer(1, 0.2*inch))
        
        # Add all KPI details
        for kpi_sheet in kpi_file.kpi_sheets:
            story.append(Paragraph(f"{kpi_sheet.code}: {kpi_sheet.name}", self.styles['CustomHeading3']))
            
            # Create detailed table for this KPI
            if kpi_sheet.period_data:
                period_data = [['Period', 'Realization', 'Target', 'Score', 'Status']]
                
                for pd in kpi_sheet.period_data:
                    period_data.append([
                        pd.period,
                        f"{pd.realization}" if pd.realization is not None else "N/A",
                        f"{pd.target}" if pd.target is not None else "N/A",
                        f"{pd.score:.1f}%" if pd.score is not None else "N/A",
                        pd.status
                    ])
                
                period_table = Table(period_data, colWidths=[1.5*inch, 1.2*inch, 1.2*inch, 1*inch, 1.6*inch])
                period_table.setStyle(TableStyle([
                    ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
                    ('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), 9),
                    ('BOTTOMPADDING', (0, 0), (-1, 0), 8),
                    ('BACKGROUND', (0, 1), (-1, -1), colors.lightgrey),
                    ('GRID', (0, 0), (-1, -1), 1, colors.black),
                    ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                ]))
                
                story.append(period_table)
                story.append(Spacer(1, 0.2*inch))

# Global PDF generator instance
pdf_generator = PDFGenerator()