"""Download a real act QR and create an HTML, PDF and DOCX with a native footnote.

Download raw.py alongside this file. Install qr_requirements.txt dependencies.
Set AMAZINGCAT_TOKEN in the environment; credentials are never written to output.
"""
import argparse
from copy import deepcopy
import html
import json
import os
from pathlib import Path

import requests
from docx import Document
from docx.enum.style import WD_STYLE_TYPE
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.opc.constants import RELATIONSHIP_TYPE as RT
from docx.opc.packuri import PackURI
from docx.opc.part import Part
from docx.shared import Mm, Pt
from lxml import etree
from weasyprint import HTML

from raw import MCP


def note_html(card, caption):
    source = html.escape(card['source_url'], quote=True)
    caption = html.escape(caption)
    return f'''<!doctype html><html lang="ru"><meta charset="utf-8">
<title>QR в сноске</title>
<style>
  @page {{ size: A4; margin: 22mm 25mm;
    @footnote {{ border-top: .25pt solid; padding-top: 3mm; }} }}
  body {{ font: 12pt/1.5 "DejaVu Sans", sans-serif; }}
  .note {{ float: footnote; font-size: 8pt; line-height: 1.3; }}
  .note::footnote-call {{ content: counter(footnote); vertical-align: super; font-size: 8pt; }}
  .note::footnote-marker {{ content: counter(footnote) ". "; }}
  .note img {{ width: 24mm; height: 24mm; padding: 2mm; background: white;
    vertical-align: top; margin-right: 3mm; }}
  .source {{ display: inline-block; width: 115mm; vertical-align: top; overflow-wrap: anywhere; }}
</style>
<h1>Ссылка на судебный акт</h1>
<p>Судебный акт указан в сноске<span class="note"><img src="qr.png" alt="QR на источник">
  <span class="source">Источник: {caption}. <a href="{source}">{source}</a></span></span>.</p>
<p>QR-код внизу страницы содержит прямую ссылку на документ на сайте суда.</p>
</html>'''


def _run(text=None):
    run = OxmlElement('w:r')
    if text is not None:
        node = OxmlElement('w:t'); node.text = text
        if text.startswith(' ') or text.endswith(' '):
            node.set(qn('xml:space'), 'preserve')
        run.append(node)
    return run


def note_docx(card, caption, image, output):
    doc = Document()
    doc.styles['Normal'].font.name = 'DejaVu Sans'
    style = doc.styles.add_style('Footnote Text', WD_STYLE_TYPE.PARAGRAPH)
    style.font.size = Pt(8)
    doc.add_heading('Ссылка на судебный акт', level=1)
    body = doc.add_paragraph('Судебный акт указан в сноске')
    reference = OxmlElement('w:footnoteReference'); reference.set(qn('w:id'), '1')
    reference_run = body.add_run(); reference_run.font.superscript = True
    reference_run._r.append(reference)
    body.add_run('.')
    doc.add_paragraph('QR-код внизу страницы содержит прямую ссылку на документ на сайте суда.')

    root = OxmlElement('w:footnotes')
    for number, kind, child in [('-1', 'separator', 'w:separator'),
                                ('0', 'continuationSeparator', 'w:continuationSeparator')]:
        footnote = OxmlElement('w:footnote'); footnote.set(qn('w:id'), number)
        footnote.set(qn('w:type'), kind)
        paragraph = OxmlElement('w:p'); run = _run(); run.append(OxmlElement(child))
        paragraph.append(run); footnote.append(paragraph); root.append(footnote)
    part = Part(PackURI('/word/footnotes.xml'),
                'application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml',
                b'', doc.part.package)
    doc.part.relate_to(part, RT.FOOTNOTES)
    footnote = OxmlElement('w:footnote'); footnote.set(qn('w:id'), '1')

    paragraph = OxmlElement('w:p')
    properties = OxmlElement('w:pPr'); pstyle = OxmlElement('w:pStyle')
    pstyle.set(qn('w:val'), 'FootnoteText'); properties.append(pstyle)
    paragraph.append(properties)
    marker = _run(); marker.append(OxmlElement('w:footnoteRef')); paragraph.append(marker)
    paragraph.append(_run(' Источник: ' + caption + '. '))
    hyperlink = OxmlElement('w:hyperlink')
    hyperlink.set(qn('r:id'), part.relate_to(card['source_url'], RT.HYPERLINK, is_external=True))
    hyperlink.append(_run(card['source_url'])); paragraph.append(hyperlink)
    footnote.append(paragraph)

    # python-docx has no public footnote-picture API. Move a real inline drawing
    # into the footnote part and give that part its own image relationship.
    picture_paragraph = doc.add_paragraph()
    picture_paragraph.paragraph_format.space_before = Mm(2)
    picture_paragraph.paragraph_format.space_after = Mm(2)
    picture_paragraph.paragraph_format.left_indent = Mm(2)
    picture_paragraph.add_run().add_picture(str(image), width=Mm(24))
    xml = deepcopy(picture_paragraph._p)
    for node in xml.iter(qn('a:blip')):
        image_part = doc.part.related_parts[node.get(qn('r:embed'))]
        node.set(qn('r:embed'), part.relate_to(image_part, RT.IMAGE))
    picture_paragraph._p.getparent().remove(picture_paragraph._p)
    footnote.append(xml); root.append(footnote)
    part._blob = etree.tostring(root, xml_declaration=True, encoding='UTF-8', standalone=True)
    footnote_properties = OxmlElement('w:footnotePr'); position = OxmlElement('w:pos')
    position.set(qn('w:val'), 'pageBottom'); footnote_properties.append(position)
    doc.settings.element.insert_element_before(footnote_properties, 'w:endnotePr',
                                              'w:compat', 'w:docVars', 'w:rsids', 'm:mathPr')
    doc.save(output)


def build(card, caption, output):
    output = Path(output); output.mkdir(parents=True, exist_ok=True)
    qr = card['qr']
    if qr['qr_encodes'] != card['source_url']:
        raise ValueError('QR target and source URL must match')
    response = requests.get(qr['qr_image_url'], timeout=30)
    response.raise_for_status()
    if not response.headers.get('Content-Type', '').startswith('image/png'):
        raise ValueError('Expected a PNG QR image')
    if not response.content.startswith(b'\x89PNG\r\n\x1a\n'):
        raise ValueError('Invalid PNG signature')
    image = output / 'qr.png'; image.write_bytes(response.content)
    # Keep only public citation fields, not the act text or MCP credentials.
    safe = {key: card[key] for key in ['doc_id', 'court', 'case_number', 'date', 'source_url', 'qr']
            if key in card}
    (output / 'qr-response.json').write_text(json.dumps(safe, ensure_ascii=False, indent=2) + '\n')
    markup = note_html(card, caption); (output / 'qr_note.html').write_text(markup)
    HTML(string=markup, base_url=str(output.resolve())).write_pdf(output / 'qr_note.pdf')
    note_docx(card, caption, image, output / 'qr_note.docx')


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--doc-id', type=int, required=True, help='doc_id from a search result')
    parser.add_argument('--court', default='ВС', choices=['ВС', 'КС', 'Пленум', 'ВАС', 'ОбзорВС'])
    parser.add_argument('--caption', required=True, help='Verified court, act date and number')
    parser.add_argument('--output', type=Path, default=Path('qr-note'))
    args = parser.parse_args()
    client = MCP(os.environ['AMAZINGCAT_TOKEN'])
    try:
        client.initialize()
        card = client.call('get_case', {'doc_id': args.doc_id, 'court': args.court})
    finally:
        client.close()
    build(card, args.caption, args.output)
    print('Created qr_note.html, qr_note.pdf, qr_note.docx, qr-response.json and qr.png')


if __name__ == '__main__':
    main()
