# -*- coding: utf-8 -*-
# Quasarr
# Project by https://github.com/rix1337

import html
import time
from datetime import datetime, timezone

from quasarr.constants import SEARCH_CAT_BOOKS, SEARCH_CAT_MUSIC
from quasarr.providers.hostname_issues import clear_hostname_issue, mark_hostname_issue
from quasarr.providers.imdb_metadata import get_localized_title, get_year
from quasarr.providers.log import debug, error, info, warn
from quasarr.providers.sessions.dd import (
    create_and_persist_session,
    retrieve_and_validate_session,
)
from quasarr.providers.utils import (
    convert_to_mb,
    generate_download_link,
    get_base_search_category_id,
    is_imdb_id,
    is_valid_release,
)

hostname = "dd"


def convert_to_rss_date(unix_timestamp):
    parsed_date = datetime.fromtimestamp(unix_timestamp, tz=timezone.utc)
    rss_date = parsed_date.strftime("%a, %d %b %Y %H:%M:%S %z")

    return rss_date


def extract_size(size_in_bytes):
    return {"size": size_in_bytes, "sizeunit": "B"}


def dd_feed(*args, **kwargs):
    return dd_search(*args, **kwargs)


def dd_search(
    shared_state,
    start_time,
    search_category,
    search_string="",
    season=None,
    episode=None,
):
    releases = []
    dd = shared_state.values["config"]("Hostnames").get(hostname.lower())
    password = dd

    base_category = get_base_search_category_id(search_category)

    if base_category in [SEARCH_CAT_BOOKS, SEARCH_CAT_MUSIC]:
        debug(f"<d>Skipping {search_category} (unsupported media type)!</d>")
        return releases

    try:
        dd_session = retrieve_and_validate_session(shared_state)
    except Exception as e:
        mark_hostname_issue(hostname, "search", str(e))
        return releases

    if not dd_session:
        info(f"Could not retrieve valid session for {dd}")
        return releases

    imdb_id = is_imdb_id(search_string)
    if imdb_id:
        search_string = get_localized_title(shared_state, imdb_id, "en")
        if not search_string:
            info(f"Could not extract title from IMDb-ID {imdb_id}")
            return releases
        search_string = html.unescape(search_string)
        if season:
            search_string += f" S{int(season):02d}"
            if episode:
                search_string += f"E{int(episode):02d}"
        else:
            if year := get_year(imdb_id):
                search_string += f" {year}"

    if not search_string:
        search_type = "feed"
        timeout = 30
    else:
        search_type = "search"
        timeout = 10

    qualities = [
        "disk-480p",
        "web-480p",
        "movie-480p-x265",
        "disk-1080p-x265",
        "web-1080p",
        "web-1080p-x265",
        "web-2160p-x265-hdr",
        "movie-1080p-x265",
        "movie-2160p-webdl-x265-hdr",
    ]

    headers = {
        "User-Agent": shared_state.values["user_agent"],
    }

    try:
        release_list = []
        for page in range(0, 100, 20):
            url = f"https://{dd}/index/search/keyword/{search_string}/qualities/{','.join(qualities)}/from/{page}/search"

            r = dd_session.get(url, headers=headers, timeout=timeout)
            r.raise_for_status()
            releases_on_page = r.json()
            if releases_on_page:
                release_list.extend(releases_on_page)

        for release in release_list:
            try:
                if release.get("fake"):
                    debug(
                        f"Release {release.get('release')} marked as fake. Invalidating session..."
                    )
                    create_and_persist_session(shared_state)
                    return []
                else:
                    title = release.get("release")

                    if not is_valid_release(
                        title, base_category, search_string, season, episode
                    ):
                        continue

                    release_imdb = release.get("imdbid", None)
                    if release_imdb and imdb_id and imdb_id != release_imdb:
                        debug(
                            f"Release {title} IMDb-ID mismatch ({imdb_id} != {release.get('imdbid', None)})"
                        )
                        continue

                    source = f"https://{dd}/"
                    size_item = extract_size(release.get("size"))
                    mb = convert_to_mb(size_item) * 1024 * 1024
                    published = convert_to_rss_date(release.get("when"))

                    link = generate_download_link(
                        shared_state,
                        title,
                        source,
                        mb,
                        password,
                        release_imdb,
                        hostname,
                    )

                    releases.append(
                        {
                            "details": {
                                "title": title,
                                "hostname": hostname.lower(),
                                "imdb_id": imdb_id,
                                "link": link,
                                "size": mb,
                                "date": published,
                                "source": source,
                            },
                            "type": "protected",
                        }
                    )
            except Exception as e:
                warn(f"Error parsing feed: {e}")
                mark_hostname_issue(
                    hostname, "search", str(e) if "e" in dir() else "Error occurred"
                )
                continue

    except Exception as e:
        error(f"Error loading feed: {e}")
        mark_hostname_issue(
            hostname, search_type, str(e) if "e" in dir() else "Error occurred"
        )

    elapsed_time = time.time() - start_time
    debug(f"Time taken: {elapsed_time:.2f}s")

    if releases:
        clear_hostname_issue(hostname)
    return releases
