"""Tests para epub_to_markdown."""

import io
import os
import struct
import sys
import zipfile

import pytest

sys.path.insert(0, os.path.dirname(__file__))
from epub_to_markdown import _html_to_markdown, _epub_via_zipfile, epub_to_markdown


# ---------------------------------------------------------------------------
# Helpers para construir EPUBs minimos en memoria
# ---------------------------------------------------------------------------

def _build_epub(files: dict[str, str]) -> str:
    """Crea un EPUB minimo como ZIP en disco y retorna el path."""
    import tempfile
    tmp = tempfile.NamedTemporaryFile(suffix='.epub', delete=False)
    with zipfile.ZipFile(tmp, 'w') as zf:
        for name, content in files.items():
            zf.writestr(name, content)
    tmp.close()
    return tmp.name


def _build_epub_with_opf(title: str, author: str, body_html: str) -> str:
    """Crea un EPUB con OPF y un documento HTML valido para ebooklib."""
    opf = f"""<?xml version='1.0' encoding='utf-8'?>
<package xmlns='http://www.idpf.org/2007/opf' unique-identifier='uid' version='2.0'>
  <metadata xmlns:dc='http://purl.org/dc/elements/1.1/'>
    <dc:title>{title}</dc:title>
    <dc:creator>{author}</dc:creator>
    <dc:identifier id='uid'>test-uid</dc:identifier>
    <dc:language>en</dc:language>
  </metadata>
  <manifest>
    <item id='ch1' href='chapter1.xhtml' media-type='application/xhtml+xml'/>
    <item id='ncx' href='toc.ncx' media-type='application/x-dtbncx+xml'/>
  </manifest>
  <spine toc='ncx'>
    <itemref idref='ch1'/>
  </spine>
</package>"""

    ncx = """<?xml version='1.0' encoding='utf-8'?>
<ncx xmlns='http://www.daisy.org/z3986/2005/ncx/' version='2005-1'>
  <head><meta name='dtb:uid' content='test-uid'/></head>
  <docTitle><text>Test</text></docTitle>
  <navMap/>
</ncx>"""

    chapter = f"""<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.1//EN' 'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head><title>Chapter</title></head>
<body>{body_html}</body>
</html>"""

    return _build_epub({
        'mimetype': 'application/epub+zip',
        'META-INF/container.xml': """<?xml version='1.0'?>
<container version='1.0' xmlns='urn:oasis:names:tc:opendocument:xmlns:container'>
  <rootfiles>
    <rootfile full-path='content.opf' media-type='application/oebps-package+xml'/>
  </rootfiles>
</container>""",
        'content.opf': opf,
        'toc.ncx': ncx,
        'chapter1.xhtml': chapter,
    })


# ---------------------------------------------------------------------------
# Tests de _html_to_markdown (pura, sin disco)
# ---------------------------------------------------------------------------

def test_html_heading_conversion():
    """conversion de headings h1-h3."""
    html = '<h1>Titulo</h1><h2>Subtitulo</h2><h3>Seccion</h3>'
    result = _html_to_markdown(html)
    assert '# Titulo' in result
    assert '## Subtitulo' in result
    assert '### Seccion' in result


def test_html_bold_italic():
    """conversion de bold e italic."""
    html = '<p><strong>negrita</strong> y <em>italica</em></p>'
    result = _html_to_markdown(html)
    assert '**negrita**' in result
    assert '*italica*' in result


def test_html_script_style_removed():
    """script y style se eliminan del output."""
    html = '<script>alert(1)</script><style>body{}</style><p>Contenido</p>'
    result = _html_to_markdown(html)
    assert 'alert' not in result
    assert 'body{}' not in result
    assert 'Contenido' in result


def test_html_entities_unescaped():
    """HTML entities se convierten a caracteres."""
    html = '<p>Tom &amp; Jerry &lt;show&gt;</p>'
    result = _html_to_markdown(html)
    assert 'Tom & Jerry' in result
    assert '<show>' in result


# ---------------------------------------------------------------------------
# Tests de epub_via_zipfile (sin ebooklib)
# ---------------------------------------------------------------------------

def test_epub_via_zipfile_extrae_html():
    """epub sin ebooklib extrae texto de archivos html."""
    path = _build_epub({
        'chapter.html': '<html><body><h1>Capitulo Uno</h1><p>Hola mundo.</p></body></html>',
    })
    try:
        result = _epub_via_zipfile(path)
        assert 'Capitulo Uno' in result
        assert 'Hola mundo' in result
    finally:
        os.unlink(path)


# ---------------------------------------------------------------------------
# Tests de epub_to_markdown (integracion)
# ---------------------------------------------------------------------------

def test_epub_con_ebooklib_metadata():
    """epub con ebooklib incluye titulo y autor en el output."""
    pytest.importorskip('ebooklib')
    path = _build_epub_with_opf(
        title='Mi Libro',
        author='Ana Perez',
        body_html='<h1>Introduccion</h1><p>Primer parrafo.</p>',
    )
    try:
        result = epub_to_markdown(path)
        assert '# Mi Libro' in result
        assert 'Ana Perez' in result
        assert 'Introduccion' in result
    finally:
        os.unlink(path)


def test_epub_corrupto_lanza_excepcion():
    """epub corrupto lanza Exception."""
    import tempfile
    tmp = tempfile.NamedTemporaryFile(suffix='.epub', delete=False)
    tmp.write(b'esto no es un epub valido')
    tmp.close()
    try:
        with pytest.raises(Exception):
            epub_to_markdown(tmp.name)
    finally:
        os.unlink(tmp.name)
