import re
from flask import Flask, jsonify, request, make_response
from config import config
from notion_to_md import export_notion_page_to_markdown
from md_to_pdf import convert_markdown_to_pdf

# Get configured logger
logger = config.get_logger(__name__)

# Initialize Flask app
app = Flask(__name__)

def sanitize_filename(title: str) -> str:
    """
    Sanitize a string to make it safe for use as a filename.
    Only allows ASCII characters to avoid HTTP header encoding issues.
    
    Args:
        title: The original title string
        
    Returns:
        str: A sanitized filename-safe string with only ASCII characters
    """
    # First, try to transliterate non-ASCII characters to ASCII equivalents
    # For Hebrew and other non-Latin scripts, this will help preserve some meaning
    sanitized = title
    
    # Replace invalid filename characters with underscores
    sanitized = re.sub(r'[<>:"/\\|?*]', '_', sanitized)
    
    # Keep only ASCII alphanumeric characters, spaces, hyphens, underscores, and dots
    # This will replace Hebrew characters and other Unicode characters with underscores
    sanitized = re.sub(r'[^a-zA-Z0-9\s\-_.]', '_', sanitized)
    
    # Replace multiple spaces/underscores with single ones and strip
    sanitized = re.sub(r'\s+', '_', sanitized)
    sanitized = re.sub(r'_{2,}', '_', sanitized)
    sanitized = sanitized.strip('_')
    
    # Limit length to avoid filesystem issues
    if len(sanitized) > 100:
        sanitized = sanitized[:100]
    
    # Ensure it's not empty and doesn't start/end with problematic characters
    if not sanitized or sanitized == '_' or not sanitized.replace('_', ''):
        sanitized = 'Untitled'
    
    return sanitized

@app.route('/page/<page_id>', methods=['GET'])
def export_page(page_id: str):
    """
    Export a Notion page to Markdown format or PDF format.
    
    Args:
        page_id: The ID of the Notion page to export
        
    Query Parameters:
        pdf: If set to 'true', returns PDF instead of Markdown
        
    Returns:
        The page content in Markdown or PDF format as a file download with page name as filename
    """
    try:
        logger.info(f"Received request to export page: {page_id}")
        
        # Check if PDF output is requested - both from query parameters and from malformed URLs
        pdf_requested = request.args.get('pdf', '').lower() == 'true'
        
        # Also check if PDF parameter is incorrectly included in the page_id (malformed URL)
        if not pdf_requested and ('&pdf=true' in page_id.lower() or '?pdf=true' in page_id.lower()):
            pdf_requested = True
            
        logger.info(f"PDF output requested: {pdf_requested}")
        
        # Clean page_id first - remove dashes and any accidentally included query parameters
        # Sometimes users might incorrectly format URLs like /page/id&pdf=true instead of /page/id?pdf=true
        clean_page_id = page_id.replace('-', '')
        if '&' in clean_page_id:
            clean_page_id = clean_page_id.split('&')[0]
        if '?' in clean_page_id:
            clean_page_id = clean_page_id.split('?')[0]
            
        logger.info(f"Cleaned page_id: {clean_page_id}")
        
        # Validate cleaned page_id format (basic validation)
        if not clean_page_id or len(clean_page_id) < 32:
            return jsonify({
                'error': 'Invalid page ID format. Page ID should be a 32-character UUID.'
            }), 400
        
        # Export the page to markdown
        page_title, markdown_content = export_notion_page_to_markdown(clean_page_id)
        
        logger.info(f"Successfully exported page '{page_title}' ({page_id}) to Markdown")
        
        # If PDF is requested, convert markdown to PDF
        if pdf_requested:
            try:
                pdf_content, pdf_filename = convert_markdown_to_pdf(markdown_content, page_title)
                
                logger.info(f"Successfully converted to PDF: {pdf_filename}")
                
                # Create response with PDF content
                response = make_response(pdf_content)
                response.headers['Content-Type'] = 'application/pdf'
                response.headers['Content-Disposition'] = f'attachment; filename="{pdf_filename}"'
                
                return response
                
            except Exception as pdf_error:
                logger.error(f"PDF conversion failed: {str(pdf_error)}")
                return jsonify({
                    'error': f'Failed to convert to PDF: {str(pdf_error)}'
                }), 500
        
        # Return markdown content with appropriate headers
        safe_filename = sanitize_filename(page_title)
        filename = f"{safe_filename}.md"
        
        logger.info(f"Suggesting filename: {filename}")
        
        headers = {
            'Content-Type': 'text/markdown; charset=utf-8',
            'Content-Disposition': f'attachment; filename="{filename}"'
        }
        
        return markdown_content, 200, headers
        
    except ValueError as e:
        logger.error(f"Configuration error: {str(e)}")
        return jsonify({
            'error': 'Server configuration error. Please check that NOTION_TOKEN is set.'
        }), 500
        
    except Exception as e:
        logger.error(f"Error exporting page {page_id}: {str(e)}")
        return jsonify({
            'error': f'Failed to export page: {str(e)}'
        }), 500

@app.route('/health', methods=['GET'])
def health_check():
    """Health check endpoint."""
    return jsonify({
        'status': 'healthy',
        'service': 'Notion to Markdown Exporter'
    }), 200

@app.route('/', methods=['GET'])
def home():
    """Home endpoint with usage instructions."""
    return jsonify({
        'service': 'Notion to Markdown Exporter',
        'usage': 'Send GET request to /page/<page_id> to export a Notion page to Markdown or PDF',
        'example': '/page/897e5a76ae524b489fdfe71f5945d1af',
        'pdf_example': '/page/897e5a76ae524b489fdfe71f5945d1af?pdf=true',
        'parameters': {
            'pdf': 'Optional. Set to "true" to get PDF output instead of Markdown'
        },
        'health_check': '/health'
    }), 200

@app.errorhandler(404)
def not_found(error):
    """Handle 404 errors."""
    return jsonify({
        'error': 'Endpoint not found',
        'usage': 'Send GET request to /page/<page_id> to export a Notion page to Markdown'
    }), 404

@app.errorhandler(500)
def internal_error(error):
    """Handle 500 errors."""
    logger.error(f"Internal server error: {str(error)}")
    return jsonify({
        'error': 'Internal server error'
    }), 500

if __name__ == '__main__':
    # Validate configuration
    try:
        config.validate_required_config()
    except ValueError as e:
        logger.error(str(e))
        exit(1)
    
    logger.info("Starting Notion to Markdown Exporter server...")
    logger.info("Available endpoints:")
    logger.info("  GET /page/<page_id> - Export Notion page to Markdown")
    logger.info("  GET /health - Health check")
    logger.info("  GET / - Service information")
    
    # Run the Flask app with configuration
    flask_config = config.get_flask_config()
    app.run(**flask_config)
