# -*- coding: utf-8 -*-

# Copyright 2025-2026 Mike Fährmann
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.

"""Extractors for https://mangareader.to/"""

from .common import ChapterExtractor, MangaExtractor
from .. import text, util

BASE_PATTERN = r"(?:https?://)?(?:www\.)?mangareader\.to"


class MangareaderBase():
    """Base class for mangareader extractors"""
    category = "mangareader"
    root = "https://mangareader.to"

    def _manga_info(self, manga_path):
        url = f"{self.root}/{manga_path}"
        html = self.request(url).text

        slug, _, mid = manga_path.rpartition("-")
        extr = text.extract_from(html)
        url = extr('property="og:url" content="', '"')
        manga = {
            "manga_url": url,
            "manga_slug": url.rpartition("/")[2].rpartition("-")[0],
            "manga_id": text.parse_int(mid),
            "manga": text.unescape(extr('class="manga-name">', "<")),
            "manga_alt": text.unescape(extr('class="manga-name-or">', "<")),
            "tags": text.split_html(extr('class="genres">', "</div>")),
            "type": text.remove_html(extr('>Type:', "</div>")),
            "status": text.remove_html(extr('>Status:', "</div>")),
            "author": text.split_html(extr('>Authors:', "</div>"))[0::2],
            "published": text.remove_html(extr('>Published:', "</div>")),
            "score": text.parse_float(text.remove_html(extr(
                '>Score:', "</div>"))),
            "views": text.parse_int(text.remove_html(extr(
                '>Views:', "</div>")).replace(",", "")),
        }

        base = self.root

        # extract all chapters
        html = extr('class="chapters-list-ul">', "    </div>")
        manga["_chapters"] = chapters = {}
        for group in text.extract_iter(html, "<ul", "</ul>"):
            lang = text.extr(group, ' id="', '-chapters"')

            chapters[lang] = current = {}
            lang = lang.partition("-")[0]
            for ch in text.extract_iter(group, "<li ", "</li>"):
                path = text.extr(ch, 'href="', '"')
                chap = text.extr(ch, 'data-number="', '"')
                name = text.unescape(text.extr(ch, 'class="name">', "<"))

                chapter, sep, minor = chap.partition(".")
                current[chap] = {
                    "title"         : name.partition(":")[2].strip(),
                    "chapter"       : text.parse_int(chapter),
                    "chapter_minor" : sep + minor,
                    "chapter_string": chap,
                    "chapter_url"   : base + path,
                    "lang"          : lang,
                }

        # extract all volumes
        html = extr('class="volume-list-ul">', "</section>")
        manga["_volumes"] = volumes = {}
        for group in html.split('<div class="manga_list-wrap')[1:]:
            lang = text.extr(group, ' id="', '-volumes"')

            volumes[lang] = current = {}
            lang = lang.partition("-")[0]
            for vol in text.extract_iter(group, 'class="item">', "</div>"):
                path = text.extr(vol, 'href="', '"')
                voln = text.extr(vol, 'tick-vol">', '<').rpartition(" ")[2]

                current[voln] = {
                    "volume"        : text.parse_int(voln),
                    "volume_cover"  : text.extr(vol, ' src="', '"'),
                    "chapter"       : 0,
                    "chapter_minor" : "",
                    "chapter_string": voln,
                    "chapter_url"   : base + path,
                    "lang"          : lang,
                }

        # extract remaining metadata
        manga["description"] = text.unescape(extr(
            'class="description-modal">', "</div>")).strip()

        return manga


class MangareaderChapterExtractor(MangareaderBase, ChapterExtractor):
    """Extractor for mangareader manga chapters"""
    directory_fmt = (
        "{category}", "{manga}",
        "{volume:?v/ />02}{chapter:?c//>03}{chapter_minor:?//}{title:?: //}")
    filename_fmt = (
        "{manga}{volume:?_v//>02}{chapter:?_c//>03}{chapter_minor:?//}_"
        "{page:>03}.{extension}")
    archive_fmt = (
        "{manga_id}_{chapter_id}_{page}")
    pattern = (BASE_PATTERN + r"/read/([\w-]+-\d+)/([^/?#]+)"
               r"/(chapter|volume)-(\d+[^/?#]*)")
    example = "https://mangareader.to/read/MANGA-123/LANG/chapter-123"

    def metadata(self, _):
        path, lang, type, chstr = self.groups

        settings = util.json_dumps({
            "readingMode"     : "vertical",
            "readingDirection": "rtl",
            "quality"         : "high",
        })
        self.cookies.set("mr_settings", settings, domain="mangareader.to")

        url = f"{self.root}/read/{path}/{lang}/{type}-{chstr}"
        page = self.request(url).text
        self.cid = cid = text.extr(page, 'data-reading-id="', '"')

        manga = self.cache(self._manga_info, path)
        return {
            **manga,
            **manga[f"_{type}s"][lang][chstr],
            "chapter_id": text.parse_int(cid),
        }

    def images(self, page):
        key = "chap" if self.groups[2] == "chapter" else "vol"
        url = f"{self.root}/ajax/image/list/{key}/{self.cid}"
        params = {
            "mode"       : "vertical,",
            "quality"    : "high,",
            "hozPageSize": "1,",
        }
        headers = {
            "X-Requested-With": "XMLHttpRequest",
        }
        html = self.request_json(url, params=params, headers=headers)["html"]

        return [
            (url, None)
            for url in text.extract_iter(html, 'data-url="', '"')
        ]


class MangareaderMangaExtractor(MangareaderBase, MangaExtractor):
    """Extractor for mangareader manga"""
    chapterclass = MangareaderChapterExtractor
    pattern = BASE_PATTERN + r"/([\w-]+-\d+)"
    example = "https://mangareader.to/MANGA-123"

    def chapters(self, page):
        manga = self.cache(self._manga_info, self.groups[0])
        lang = self.config("lang") or "en"

        return [
            (info["chapter_url"], {**manga, **info})
            for info in manga["_chapters"][lang].values()
        ]
