from pathlib import Path
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Preformatted, PageBreak
from reportlab.platypus.tableofcontents import TableOfContents
from xml.sax.saxutils import escape
import re

root = Path(r'E:\xampp\htdocs\laravel12-crypto-gateway-api-final\laravel12-crypto-gateway-api')
md_path = root / 'WORKFLOW.md'
out_dir = root / 'output' / 'pdf'
out_dir.mkdir(parents=True, exist_ok=True)
pdf_path = out_dir / 'ProlificEx_Workflow.pdf'
text = md_path.read_text(encoding='utf-8')
text = text.replace('|`r`n        v', '|\n        v').replace('        ?', '        |\n        v')
md_path.write_text(text, encoding='utf-8')

styles = getSampleStyleSheet()
styles.add(ParagraphStyle(name='DocTitle', parent=styles['Title'], fontName='Helvetica-Bold', fontSize=22, leading=28, textColor=colors.HexColor('#13233a'), spaceAfter=16))
styles.add(ParagraphStyle(name='H1x', parent=styles['Heading1'], fontName='Helvetica-Bold', fontSize=16, leading=20, textColor=colors.HexColor('#173b63'), spaceBefore=14, spaceAfter=8))
styles.add(ParagraphStyle(name='H2x', parent=styles['Heading2'], fontName='Helvetica-Bold', fontSize=12.5, leading=16, textColor=colors.HexColor('#24577f'), spaceBefore=10, spaceAfter=6))
styles.add(ParagraphStyle(name='Bodyx', parent=styles['BodyText'], fontName='Helvetica', fontSize=9.5, leading=13, spaceAfter=6))
styles.add(ParagraphStyle(name='Codex', parent=styles['Code'], fontName='Courier', fontSize=7.2, leading=9, leftIndent=8, rightIndent=8, backColor=colors.HexColor('#f4f6f8'), borderColor=colors.HexColor('#dde3ea'), borderWidth=0.5, borderPadding=6, spaceBefore=4, spaceAfter=8))
styles.add(ParagraphStyle(name='Smallx', parent=styles['BodyText'], fontName='Helvetica', fontSize=8, leading=10, textColor=colors.HexColor('#5b6570')))

class NumberedDocTemplate(SimpleDocTemplate):
    def afterFlowable(self, flowable):
        if isinstance(flowable, Paragraph):
            text = flowable.getPlainText()
            style = flowable.style.name
            if style == 'H1x':
                key = 'h1-%s' % self.seq.nextf('heading')
                self.canv.bookmarkPage(key)
                self.notify('TOCEntry', (0, text, self.page, key))
            elif style == 'H2x':
                key = 'h2-%s' % self.seq.nextf('heading')
                self.canv.bookmarkPage(key)
                self.notify('TOCEntry', (1, text, self.page, key))

def footer(canvas, doc):
    canvas.saveState()
    canvas.setFont('Helvetica', 8)
    canvas.setFillColor(colors.HexColor('#697386'))
    canvas.drawString(doc.leftMargin, 0.45 * inch, 'ProlificEx Crypto Gateway API - Workflow Document')
    canvas.drawRightString(A4[0] - doc.rightMargin, 0.45 * inch, f'Page {doc.page}')
    canvas.restoreState()

def inline_markup(s):
    s = escape(s)
    s = re.sub(r'`([^`]+)`', r'<font name="Courier">\1</font>', s)
    return s

story = []
lines = text.splitlines()
if lines and lines[0].startswith('# '):
    story.append(Paragraph(inline_markup(lines[0][2:].strip()), styles['DocTitle']))
    lines = lines[1:]
else:
    story.append(Paragraph('ProlificEx Crypto Gateway API - Workflow Document', styles['DocTitle']))

story.append(Paragraph('Generated from WORKFLOW.md. This PDF explains the current Laravel API workflows, testing order, authentication, deposits, balances, withdrawals, webhooks, subscriptions, and production gaps.', styles['Smallx']))
story.append(Spacer(1, 12))
toc = TableOfContents()
toc.levelStyles = [
    ParagraphStyle(fontName='Helvetica', fontSize=9, name='TOC0', leftIndent=0, firstLineIndent=0, spaceBefore=3, leading=11),
    ParagraphStyle(fontName='Helvetica', fontSize=8, name='TOC1', leftIndent=14, firstLineIndent=0, spaceBefore=1, leading=10),
]
story.append(Paragraph('Table of Contents', styles['H1x']))
story.append(toc)
story.append(PageBreak())

in_code = False
code_lines = []
para_lines = []

def flush_para():
    global para_lines
    if para_lines:
        paragraph = ' '.join(x.strip() for x in para_lines if x.strip())
        if paragraph:
            story.append(Paragraph(inline_markup(paragraph), styles['Bodyx']))
        para_lines.clear()

def flush_code():
    global code_lines
    code = '\n'.join(code_lines).rstrip()
    if code:
        story.append(Preformatted(code, styles['Codex'], maxLineLength=92))
    code_lines.clear()

for raw in lines:
    line = raw.rstrip('\n')
    if line.startswith('```'):
        if in_code:
            flush_code()
            in_code = False
        else:
            flush_para()
            in_code = True
        continue
    if in_code:
        code_lines.append(line)
        continue
    if line.strip() == '---':
        flush_para()
        story.append(Spacer(1, 8))
        continue
    if line.startswith('## '):
        flush_para()
        story.append(Paragraph(inline_markup(line[3:].strip()), styles['H1x']))
        continue
    if line.startswith('### '):
        flush_para()
        story.append(Paragraph(inline_markup(line[4:].strip()), styles['H2x']))
        continue
    if not line.strip():
        flush_para()
        continue
    para_lines.append(line)

flush_para()

doc = NumberedDocTemplate(str(pdf_path), pagesize=A4, rightMargin=0.58*inch, leftMargin=0.58*inch, topMargin=0.62*inch, bottomMargin=0.72*inch)
doc.multiBuild(story, onFirstPage=footer, onLaterPages=footer)
print(pdf_path)
