"""Live addon settings for the background service (Addon.getSetting is cached there)."""
from __future__ import annotations

import time
import xml.etree.ElementTree as ET

import xbmcgui
import xbmcvfs

from xbmcaddon import Addon

from .constants import ADDON_ID, SETTINGS_EPOCH_PROP, SHOW_ARCHIVE_BADGE_PROP

_HOME = xbmcgui.Window(10000)
_SETTING_ID = "show_archive_badge"
_DEFAULT_ENABLED = True


def _settings_path_candidates() -> list[str]:
    templates = (
        "special://profile/addon_data/{id}/settings.xml",
        "special://masterprofile/addon_data/{id}/settings.xml",
        "special://home/userdata/addon_data/{id}/settings.xml",
        "special://home/addon_data/{id}/settings.xml",
    )
    return [xbmcvfs.translatePath(t.format(id=ADDON_ID)) for t in templates]


def resolve_settings_xml_path() -> str | None:
    for path in _settings_path_candidates():
        if xbmcvfs.exists(path):
            return path
    return None


def _read_text(path: str) -> str | None:
    try:
        handle = xbmcvfs.File(path)
        try:
            raw = handle.read()
        finally:
            handle.close()
        if isinstance(raw, bytes):
            return raw.decode("utf-8", errors="replace")
        return str(raw) if raw is not None else None
    except Exception:
        return None


def _parse_bool(raw: str | None, default: bool = _DEFAULT_ENABLED) -> bool:
    text = (raw or "").strip().lower()
    if text in ("false", "0", "no"):
        return False
    if text in ("true", "1", "yes"):
        return True
    return default


def read_show_archive_badge_from_disk() -> bool | None:
    path = resolve_settings_xml_path()
    if not path:
        return None
    text = _read_text(path)
    if not text:
        return None
    try:
        root = ET.fromstring(text)
    except ET.ParseError:
        return None
    for node in root.findall("setting"):
        if node.get("id") != _SETTING_ID:
            continue
        return _parse_bool(node.text, _parse_bool(node.get("default"), _DEFAULT_ENABLED))
    return None


def read_show_archive_badge_from_addon(addon: Addon) -> bool:
    getter = getattr(addon, "getSettingBool", None)
    if callable(getter):
        return bool(getter(_SETTING_ID))
    return _parse_bool(addon.getSetting(_SETTING_ID))


def publish_show_archive_badge(enabled: bool) -> None:
    _HOME.setProperty(SHOW_ARCHIVE_BADGE_PROP, "1" if enabled else "0")
    _HOME.setProperty(SETTINGS_EPOCH_PROP, str(time.time()))


def publish_from_addon(addon: Addon) -> bool:
    enabled = read_show_archive_badge_from_addon(addon)
    publish_show_archive_badge(enabled)
    return enabled


def read_show_archive_badge_live() -> bool:
    """For the overlay service: read fresh values, never Addon.getSetting()."""
    on_disk = read_show_archive_badge_from_disk()
    if on_disk is not None:
        prop = _HOME.getProperty(SHOW_ARCHIVE_BADGE_PROP)
        expected = "1" if on_disk else "0"
        if prop != expected:
            publish_show_archive_badge(on_disk)
        return on_disk

    prop = _HOME.getProperty(SHOW_ARCHIVE_BADGE_PROP)
    if prop in ("0", "1"):
        return prop == "1"
    return _DEFAULT_ENABLED
