import asyncio
from gettext import gettext as _
from pathlib import Path

from gi.repository import Gio, GObject, Gtk

from .config import PKGDATADIR

_PANDOC_DEFAULTS_FILE = Path(PKGDATADIR, "defaults.yaml")


class ConversionError(Exception):
    """Raised if the Pandoc conversion failed."""


class Format(GObject.Object):
    """A document format."""

    __gtype_name__ = "Format"

    name = GObject.Property(type=str)
    pandoc_id = GObject.Property(type=str)
    extension = GObject.Property(type=str)
    supports_font_style = GObject.Property(type=bool, default=False)

    def __init__(
        self,
        name: str,
        pandoc_id: str,
        extension: str,
        *,
        supports_font_style: bool = False,
    ) -> None:
        super().__init__()

        self.name = name
        self.pandoc_id = pandoc_id
        self.extension = extension
        self.supports_font_style = supports_font_style


class Document(GObject.Object):
    """A document data object."""

    __gtype_name__ = "Document"

    path = GObject.Property(type=str)
    name = GObject.Property(type=str)
    icon = GObject.Property(type=Gio.Icon)

    async def convert(
        self,
        *,
        output_path: str,
        document_format: Format,
        font_style: str,
    ) -> None:
        """Convert the document."""
        process = await asyncio.create_subprocess_exec(
            "pandoc",
            self.path,
            f"--defaults={_PANDOC_DEFAULTS_FILE}",
            f"--variable=mainfont:{font_style}",
            f"--to={document_format.pandoc_id}",
            f"--output={output_path}",
        )

        if await process.wait() != 0:
            raise ConversionError


INPUT_MIME_TYPES = (
    "application/docbook+xml",
    "application/epub+zip",
    "application/rtf",
    "application/vnd.oasis.docbook+xml",
    "application/vnd.oasis.opendocument.text",
    "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    "application/x-docbook+xml",
    "application/x-fictionbook",
    "application/x-fictionbook+xml",
    "application/x-ipynb+json",
    "application/x-research-info-systems",
    "application/x-zip-compressed-fb2",
    "text/csv",
    "text/html",
    "text/markdown",
    "text/plain",
    "text/tab-separated-values",
    "text/x-bibtex",
    "text/x-comma-separated-values",
    "text/x-csv",
    "text/x-opml",
    "text/x-opml+xml",
    "text/x-rst",
    "text/x-tex",
    "text/x-txt2tags",
    "text/x-typst",
    "text/x-wiki",
)
INPUT_SUFFIXES = (
    "html",
    "muse",
    "org",
    "ris",
)
INPUT_FILTER = Gtk.FileFilter(
    name=_("Document"),
    mime_types=INPUT_MIME_TYPES,
    suffixes=INPUT_SUFFIXES,
)

OUTPUT_FORMATS = (
    Format("PDF", "pdf", "pdf", supports_font_style=True),
    Format("Markdown", "markdown_strict", "md"),
    Format("reStructuredText", "rst", "rst"),
    Format("LaTeX", "latex", "tex"),
    Format("HTML", "html5", "html", supports_font_style=True),
    Format("Microsoft Word", "docx", "docx"),
    Format("OpenOffice/LibreOffice", "odt", "odt"),
    Format("Rich Text Format", "rtf", "rtf"),
    Format("EPUB", "epub3", "epub"),
    Format("AsciiDoc", "asciidoc", "adoc"),
)
OUTPUT_FORMATS_MODEL = Gio.ListStore.new(Format)
OUTPUT_FORMATS_MODEL.splice(0, 0, OUTPUT_FORMATS)

HELP_URL = "https://pandoc.org/help.html"
