#!/usr/bin/env python3

import markdown2
from reportlab.lib.pagesizes import letter, A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak
from reportlab.platypus.tableofcontents import TableOfContents
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY

import re
import os
from datetime import datetime

def clean_text_for_reportlab(text):
    """Clean text for ReportLab compatibility"""
    if not text:
        return ""
    # Replace problematic characters
    text = text.replace('&', '&amp;')
    text = text.replace('<', '&lt;')
    text = text.replace('>', '&gt;')
    text = text.replace('✅', '✓')  # Replace checkmark with simpler character
    return text

def parse_markdown_to_structured_content(markdown_content):
    """Parse markdown into structured content for PDF generation"""
    
    lines = markdown_content.split('\n')
    content = []
    current_section = None
    current_paragraph = []
    in_code_block = False
    code_block_lines = []
    current_table = []
    in_table = False
    
    for line in lines:
        line = line.rstrip()
        
        # Handle code blocks
        if line.startswith('```'):
            if in_code_block:
                # End code block
                content.append({
                    'type': 'code',
                    'content': '\n'.join(code_block_lines),
                    'language': current_language if 'current_language' in locals() else ''
                })
                code_block_lines = []
                in_code_block = False
            else:
                # Start code block
                current_language = line[3:].strip()
                in_code_block = True
            continue
        
        if in_code_block:
            code_block_lines.append(line)
            continue
        
        # Handle tables
        if '|' in line and line.strip().startswith('|'):
            if not in_table:
                in_table = True
                current_table = []
            current_table.append(line)
            continue
        else:
            if in_table:
                content.append({'type': 'table', 'content': current_table})
                current_table = []
                in_table = False
        
        # Handle headings
        if line.startswith('#'):
            if current_paragraph:
                content.append({'type': 'paragraph', 'content': ' '.join(current_paragraph)})
                current_paragraph = []
            
            level = len(line) - len(line.lstrip('#'))
            title = line.lstrip('# ').strip()
            content.append({'type': 'heading', 'level': level, 'content': title})
            continue
        
        # Handle horizontal rules
        if line.strip() == '---':
            content.append({'type': 'hr'})
            continue
        
        # Handle empty lines
        if not line.strip():
            if current_paragraph:
                content.append({'type': 'paragraph', 'content': ' '.join(current_paragraph)})
                current_paragraph = []
            continue
        
        # Handle list items
        if line.lstrip().startswith(('- ', '* ', '+ ')) or re.match(r'^\s*\d+\.\s', line):
            if current_paragraph:
                content.append({'type': 'paragraph', 'content': ' '.join(current_paragraph)})
                current_paragraph = []
            content.append({'type': 'list_item', 'content': line.strip()})
            continue
        
        # Regular text
        current_paragraph.append(line.strip())
    
    # Don't forget remaining content
    if current_paragraph:
        content.append({'type': 'paragraph', 'content': ' '.join(current_paragraph)})
    if in_table and current_table:
        content.append({'type': 'table', 'content': current_table})
    
    return content

def create_styles():
    """Create custom styles for the PDF"""
    styles = getSampleStyleSheet()
    
    # Custom heading styles
    styles.add(ParagraphStyle(
        name='CustomH1',
        parent=styles['Heading1'],
        fontSize=24,
        spaceAfter=20,
        spaceBefore=30,
        textColor=colors.HexColor('#2c3e50'),
        borderPadding=10,
    ))
    
    styles.add(ParagraphStyle(
        name='CustomH2',
        parent=styles['Heading2'],
        fontSize=20,
        spaceAfter=15,
        spaceBefore=25,
        textColor=colors.HexColor('#34495e'),
        borderPadding=8,
    ))
    
    styles.add(ParagraphStyle(
        name='CustomH3',
        parent=styles['Heading3'],
        fontSize=16,
        spaceAfter=12,
        spaceBefore=20,
        textColor=colors.HexColor('#2980b9'),
    ))
    
    styles.add(ParagraphStyle(
        name='CustomH4',
        parent=styles['Heading4'],
        fontSize=14,
        spaceAfter=10,
        spaceBefore=15,
        textColor=colors.HexColor('#8e44ad'),
    ))
    
    styles.add(ParagraphStyle(
        name='CustomH5',
        parent=styles['Heading5'],
        fontSize=12,
        spaceAfter=8,
        spaceBefore=12,
        textColor=colors.HexColor('#16a085'),
    ))
    
    styles.add(ParagraphStyle(
        name='CustomH6',
        parent=styles['Heading6'],
        fontSize=11,
        spaceAfter=6,
        spaceBefore=10,
        textColor=colors.HexColor('#27ae60'),
    ))
    
    # Custom paragraph style
    styles.add(ParagraphStyle(
        name='CustomNormal',
        parent=styles['Normal'],
        fontSize=11,
        spaceAfter=12,
        alignment=TA_JUSTIFY,
        leftIndent=0,
        rightIndent=0,
    ))
    
    # Code style
    styles.add(ParagraphStyle(
        name='CustomCode',
        parent=styles['Normal'],
        fontSize=9,
        fontName='Courier',
        textColor=colors.HexColor('#e74c3c'),
        backColor=colors.HexColor('#f8f9fa'),
        borderColor=colors.HexColor('#e9ecef'),
        borderWidth=1,
        borderPadding=10,
        spaceAfter=12,
        spaceBefore=12,
    ))
    
    return styles

def parse_table(table_lines):
    """Parse markdown table into reportlab Table data"""
    if not table_lines:
        return None
    
    # Remove empty lines
    table_lines = [line for line in table_lines if line.strip()]
    
    data = []
    for i, line in enumerate(table_lines):
        # Skip separator lines (like |---|---|)
        if re.match(r'^\|\s*:?-+:?\s*\|\s*:?-+:?\s*', line):
            continue
        
        # Split by | and clean up
        cells = [cell.strip() for cell in line.split('|')[1:-1]]  # Remove first and last empty parts
        if cells:
            data.append(cells)
    
    return data if data else None

def convert_markdown_to_pdf(markdown_file, output_file):
    """Convert markdown to professional PDF using ReportLab"""
    
    # Read the markdown file
    with open(markdown_file, 'r', encoding='utf-8') as f:
        markdown_content = f.read()
    
    # Parse markdown into structured content
    structured_content = parse_markdown_to_structured_content(markdown_content)
    
    # Create PDF document
    doc = SimpleDocTemplate(
        output_file,
        pagesize=A4,
        topMargin=1*inch,
        bottomMargin=1*inch,
        leftMargin=1*inch,
        rightMargin=1*inch,
        title="Retool Product Analytics Strategy"
    )
    
    # Create styles
    styles = create_styles()
    
    # Build content
    story = []
    
    # Add title page elements
    story.append(Paragraph("Retool Product Analytics Strategy", styles['CustomH1']))
    story.append(Paragraph("Building Analytics Excellence for the AI-Native Development Platform", styles['CustomH3']))
    story.append(Spacer(1, 0.5*inch))
    story.append(Paragraph(f"Generated on {datetime.now().strftime('%B %d, %Y')}", styles['Normal']))
    story.append(PageBreak())
    
    # Process content
    for item in structured_content:
        if item['type'] == 'heading':
            level = item['level']
            text = clean_text_for_reportlab(item['content'])
            
            if level == 1:
                story.append(Paragraph(text, styles['CustomH1']))
            elif level == 2:
                story.append(Paragraph(text, styles['CustomH2']))
            elif level == 3:
                story.append(Paragraph(text, styles['CustomH3']))
            elif level == 4:
                story.append(Paragraph(text, styles['CustomH4']))
            elif level == 5:
                story.append(Paragraph(text, styles['CustomH5']))
            else:
                story.append(Paragraph(text, styles['CustomH6']))
        
        elif item['type'] == 'paragraph':
            text = clean_text_for_reportlab(item['content'])
            if text.strip():
                # Handle bold and italic formatting
                text = re.sub(r'\*\*(.*?)\*\*', r'<b>\1</b>', text)
                text = re.sub(r'\*(.*?)\*', r'<i>\1</i>', text)
                text = re.sub(r'`(.*?)`', r'<font name="Courier" color="#e74c3c">\1</font>', text)
                story.append(Paragraph(text, styles['CustomNormal']))
        
        elif item['type'] == 'list_item':
            text = clean_text_for_reportlab(item['content'])
            # Remove markdown list markers
            text = re.sub(r'^[-*+]\s+', '• ', text)
            text = re.sub(r'^\d+\.\s+', '• ', text)
            # Handle checkboxes
            text = text.replace('- [ ]', '☐')
            text = text.replace('- [x]', '✓')
            text = text.replace('- [X]', '✓')
            # Handle formatting
            text = re.sub(r'\*\*(.*?)\*\*', r'<b>\1</b>', text)
            text = re.sub(r'\*(.*?)\*', r'<i>\1</i>', text)
            text = re.sub(r'`(.*?)`', r'<font name="Courier" color="#e74c3c">\1</font>', text)
            
            story.append(Paragraph(text, styles['Normal']))
        
        elif item['type'] == 'code':
            code_text = clean_text_for_reportlab(item['content'])
            story.append(Paragraph(f'<font name="Courier">{code_text}</font>', styles['CustomCode']))
        
        elif item['type'] == 'table':
            table_data = parse_table(item['content'])
            if table_data:
                # Clean table data
                clean_table_data = []
                for row in table_data:
                    clean_row = [clean_text_for_reportlab(cell) for cell in row]
                    clean_table_data.append(clean_row)
                
                table = Table(clean_table_data, hAlign='LEFT')
                
                # Style the table
                table_style = TableStyle([
                    ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#ecf0f1')),  # Header background
                    ('TEXTCOLOR', (0, 0), (-1, 0), colors.HexColor('#2c3e50')),   # Header text color
                    ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
                    ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),  # Header font
                    ('FONTSIZE', (0, 0), (-1, 0), 10),
                    ('FONTNAME', (0, 1), (-1, -1), 'Helvetica'),      # Body font
                    ('FONTSIZE', (0, 1), (-1, -1), 9),
                    ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
                    ('GRID', (0, 0), (-1, -1), 1, colors.HexColor('#bdc3c7')),
                    ('VALIGN', (0, 0), (-1, -1), 'TOP'),
                ])
                
                # Alternate row colors
                for i in range(1, len(clean_table_data)):
                    if i % 2 == 0:
                        table_style.add('BACKGROUND', (0, i), (-1, i), colors.HexColor('#f8f9fa'))
                
                table.setStyle(table_style)
                story.append(table)
                story.append(Spacer(1, 12))
        
        elif item['type'] == 'hr':
            story.append(Spacer(1, 12))
            # Create a simple line
            story.append(Paragraph('<para borderWidth="1" borderColor="#bdc3c7"><br/></para>', styles['Normal']))
            story.append(Spacer(1, 12))
    
    # Build PDF
    doc.build(story)
    
    return os.path.getsize(output_file)

if __name__ == "__main__":
    input_file = "/Users/igloo/.openclaw/workspace/scratch/retool-product-analytics-plan.md"
    output_file = "/Users/igloo/.openclaw/workspace/scratch/retool-product-analytics-plan.pdf"
    
    print("Converting markdown to PDF using ReportLab...")
    
    try:
        file_size = convert_markdown_to_pdf(input_file, output_file)
        print(f"✅ PDF successfully generated!")
        print(f"📄 Output file: {output_file}")
        print(f"📊 File size: {file_size:,} bytes ({file_size / (1024*1024):.2f} MB)")
        
    except Exception as e:
        print(f"❌ Error during conversion: {e}")
        raise