import base64
import os
import re
import tempfile
from flask import Flask, request, Response, jsonify
from weasyprint import HTML

application = Flask(__name__)

MAX_HTML_BYTES = int(os.environ.get('PDF_MAX_HTML_BYTES', str(8 * 1024 * 1024)))
PDF_TOKEN = os.environ.get('PDF_SERVICE_TOKEN', '').strip()


def _safe_filename(value: str) -> str:
    value = (value or 'document.pdf').strip()
    value = re.sub(r'[^A-Za-z0-9._-]+', '-', value)
    value = value.strip('-_.') or 'document'
    if not value.lower().endswith('.pdf'):
        value += '.pdf'
    return value


def _request_data():
    if request.is_json:
        return request.get_json(silent=True) or {}
    return request.form.to_dict(flat=True)


@application.get('/')
def index():
    return 'Tech Waves PDF service is running', 200, {'Content-Type': 'text/plain; charset=utf-8'}


@application.get('/health')
def health():
    return jsonify({'ok': True, 'engine': 'weasyprint'})


@application.post('/render')
def render():
    if PDF_TOKEN:
        incoming = request.headers.get('X-PDF-Token', '').strip()
        if incoming != PDF_TOKEN:
            return jsonify({'error': 'Forbidden'}), 403

    if request.content_length is not None and request.content_length > int(MAX_HTML_BYTES * 1.5):
        return jsonify({'error': 'HTML payload is too large'}), 413

    data = _request_data()
    html = data.get('html') or ''
    html_b64 = data.get('html_b64') or ''
    if html_b64:
        try:
            html = base64.b64decode(html_b64.encode('ascii'), validate=True).decode('utf-8')
        except Exception as exc:
            return jsonify({'error': 'INVALID_HTML_B64', 'message': str(exc)}), 422

    if not isinstance(html, str) or not html.strip():
        return jsonify({'error': 'Missing html'}), 422
    if len(html.encode('utf-8')) > MAX_HTML_BYTES:
        return jsonify({'error': 'HTML payload is too large'}), 413

    base_url = data.get('base_url') or request.url_root
    filename = _safe_filename(str(data.get('filename') or 'document.pdf'))

    try:
        with tempfile.TemporaryDirectory(prefix='tw_pdf_'):
            pdf_bytes = HTML(string=html, base_url=base_url).write_pdf()
    except Exception as exc:
        return jsonify({'error': 'PDF_RENDER_FAILED', 'message': str(exc)}), 500

    return Response(
        pdf_bytes,
        mimetype='application/pdf',
        headers={
            'Content-Disposition': f'inline; filename="{filename}"',
            'Cache-Control': 'no-store',
        },
    )
