from pathlib import Path
from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile, ZipInfo


ROOT = Path(__file__).parent
OUTPUT = ROOT / "four-chapter-web-novel-fixture.epub"
FIXED_TIME = (2026, 9, 17, 0, 0, 0)

CHAPTERS = [
    ("chapter-01.xhtml", "Chapter 1: The Station at Dawn", "Mara found the brass key beneath the timetable. The first train had not arrived, but someone had already crossed out her destination."),
    ("chapter-02.xhtml", "Chapter 2: A Name Written Twice", "The ledger used two spellings for the same village: Vale Orin and Valé-Orin. Mara circled both so an editor could choose one form before translation."),
    ("chapter-03.xhtml", "Chapter 3: The Long Message That Must Reflow Without Clipping", "A courier left a deliberately long sentence to test reflow, punctuation, emphasis, and line breaking in a narrow reading window without relying on fixed page dimensions."),
    ("chapter-04.xhtml", "Chapter 4: Scripts at the Border", "The archive label included mixed scripts—東京, العربية, and Ελληνικά—so the package could expose missing-character or direction problems before a full translation run."),
]

MIMETYPE = "application/epub+zip"
CONTAINER = """<?xml version="1.0" encoding="UTF-8"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
  <rootfiles><rootfile full-path="EPUB/package.opf" media-type="application/oebps-package+xml"/></rootfiles>
</container>
"""
STYLE = "body { font-family: serif; line-height: 1.55; margin: 5%; } h1 { break-before: page; } .note { border-left: 0.2rem solid #666; padding-left: 0.8rem; }"


def xhtml(title: str, body: str) -> str:
    return f"""<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head><title>{title}</title><link rel="stylesheet" type="text/css" href="style.css"/></head>
<body><h1>{title}</h1><p>{body}</p><p class="note">Fixture note: preserve chapter boundaries, inline punctuation, and this callout during conversion.</p></body>
</html>
"""


nav_items = "".join(f'<li><a href="{name}">{title}</a></li>' for name, title, _ in CHAPTERS)
NAV = f"""<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en" lang="en">
<head><title>Contents</title></head><body><nav epub:type="toc" id="toc"><h1>Contents</h1><ol>{nav_items}</ol></nav></body>
</html>
"""

manifest = "\n".join(f'    <item id="c{i}" href="{name}" media-type="application/xhtml+xml"/>' for i, (name, _, _) in enumerate(CHAPTERS, 1))
spine = "\n".join(f'    <itemref idref="c{i}"/>' for i in range(1, len(CHAPTERS) + 1))
PACKAGE = f"""<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" unique-identifier="pub-id" xml:lang="en">
  <metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
    <dc:identifier id="pub-id">urn:uuid:6f425df5-0fcf-447f-874b-76b4107b43d2</dc:identifier>
    <dc:title>The Border Archive</dc:title><dc:creator>BookTranslator Test Fixture</dc:creator><dc:language>en</dc:language>
    <meta property="dcterms:modified">2026-09-17T00:00:00Z</meta>
  </metadata>
  <manifest>
    <item id="nav" href="nav.xhtml" media-type="application/xhtml+xml" properties="nav"/>
    <item id="css" href="style.css" media-type="text/css"/>
{manifest}
  </manifest>
  <spine>
{spine}
  </spine>
</package>
"""


def write_entry(book: ZipFile, name: str, data: str, compression: int) -> None:
    info = ZipInfo(name, FIXED_TIME)
    info.compress_type = compression
    info.external_attr = 0o644 << 16
    book.writestr(info, data.encode("utf-8"))


with ZipFile(OUTPUT, "w") as book:
    write_entry(book, "mimetype", MIMETYPE, ZIP_STORED)
    write_entry(book, "META-INF/container.xml", CONTAINER, ZIP_DEFLATED)
    write_entry(book, "EPUB/package.opf", PACKAGE, ZIP_DEFLATED)
    write_entry(book, "EPUB/nav.xhtml", NAV, ZIP_DEFLATED)
    write_entry(book, "EPUB/style.css", STYLE, ZIP_DEFLATED)
    for name, title, body in CHAPTERS:
        write_entry(book, f"EPUB/{name}", xhtml(title, body), ZIP_DEFLATED)

print(OUTPUT)
