import xml.etree.ElementTree as ET
from pathlib import Path

# Default XML content to write if missing
DEFAULT_XML = """<?xml version="1.0" encoding="UTF-8"?>
<config>
  <general>
    <processing_folder>processing</processing_folder>
    <suffix> -EHX</suffix>
    <extensions>.mkv,.mp4</extensions>
    <ignore_tags>ehx,megusta</ignore_tags>
    <reduction_ratio_threshold>0.5</reduction_ratio_threshold>
  </general>
  <path_mappings>
    <map from="P:\\tv" to="/mnt/plex/tv" />
    <map from="P:\\anime" to="/mnt/plex/anime" />
  </path_mappings>
  <encode>
    <cq>
      <tv_1080>28</tv_1080>
      <tv_720>32</tv_720>
      <movie_1080>32</movie_1080>
      <movie_720>34</movie_720>
    </cq>
    <fallback>
      <bitrate_1080>1500k</bitrate_1080>
      <maxrate_1080>1750k</maxrate_1080>
      <bufsize_1080>2750k</bufsize_1080>
      <bitrate_720>900k</bitrate_720>
      <maxrate_720>1250k</maxrate_720>
      <bufsize_720>1800k</bufsize_720>
    </fallback>
    <filters>
      <default>lanczos</default>
      <tv>bicubic</tv>
    </filters>
  </encode>
  <audio>
    <stereo>
      <low>64000</low>
      <medium>128000</medium>
      <high>160000</high>
    </stereo>
    <multi_channel>
      <low>384000</low>
      <medium>512000</medium>
      <high>640000</high>
    </multi_channel>
  </audio>
</config>
"""

def load_config_xml(path: Path) -> dict:
    if not path.exists():
        path.write_text(DEFAULT_XML, encoding="utf-8")
        print(f"ℹ️  Created default config.xml at {path}")

    tree = ET.parse(path)
    root = tree.getroot()

    # --- General ---
    general = root.find("general")
    processing_folder_elem = general.find("processing_folder") if general is not None else None
    processing_folder = processing_folder_elem.text if processing_folder_elem is not None else "processing"

    suffix_elem = general.find("suffix") if general is not None else None
    suffix = suffix_elem.text if suffix_elem is not None else " -EHX"

    extensions_elem = general.find("extensions") if general is not None else None
    extensions = extensions_elem.text.split(",") if extensions_elem is not None else [".mkv", ".mp4"]

    ignore_tags_elem = general.find("ignore_tags") if general is not None else None
    ignore_tags = ignore_tags_elem.text.split(",") if ignore_tags_elem is not None else ["ehx", "megusta"]

    reduction_ratio_elem = general.find("reduction_ratio_threshold") if general is not None else None
    reduction_ratio_threshold = float(reduction_ratio_elem.text) if reduction_ratio_elem is not None else 0.5

    # Extract general section as nested dict for other settings
    general_dict = {}
    if general is not None:
        # Subtitles
        subtitles_elem = general.find("subtitles")
        if subtitles_elem is not None:
            general_dict["subtitles"] = {
                "enabled": subtitles_elem.find("enabled").text.lower() == "true" if subtitles_elem.find("enabled") is not None else True,
                "extensions": subtitles_elem.find("extensions").text if subtitles_elem.find("extensions") is not None else ".vtt,.srt,.ass,.ssa,.sub",
                "codec": subtitles_elem.find("codec").text if subtitles_elem.find("codec") is not None else "srt"
            }
        
        # Audio filter
        audio_filter_elem = general.find("audio_filter")
        if audio_filter_elem is not None:
            general_dict["audio_filter"] = {
                "enabled": audio_filter_elem.find("enabled").text.lower() == "true" if audio_filter_elem.find("enabled") is not None else False
            }
        
        # Default language for undefined audio tracks
        default_language_elem = general.find("default_language")
        if default_language_elem is not None:
            general_dict["default_language"] = default_language_elem.text if default_language_elem.text else "eng"

    # --- Path Mappings ---
    path_mappings = []
    for m in root.findall("path_mappings/map"):
        f = m.attrib.get("from")
        t = m.attrib.get("to")
        if f and t:
            path_mappings.append({"from": f, "to": t})

    # --- Encode ---
    encode_elem = root.find("encode")
    cq = {}
    fallback = {}
    filters = {}
    if encode_elem is not None:
        cq_elem = encode_elem.find("cq")
        if cq_elem is not None:
            # Check if CQ has encoder-specific sub-elements (av1, hevc)
            encoder_elems = list(cq_elem)
            if encoder_elems and encoder_elems[0].tag in ["av1", "hevc"]:
                # New nested structure with encoder-specific CQ values
                for encoder_tag in cq_elem:
                    if encoder_tag.tag in ["av1", "hevc"]:
                        cq[encoder_tag.tag] = {}
                        for child in encoder_tag:
                            if child.text and child.text.strip():
                                cq[encoder_tag.tag][child.tag] = int(child.text.strip())
            else:
                # Old flat structure (backwards compatibility)
                for child in cq_elem:
                    if child.text and child.text.strip():
                        cq[child.tag] = int(child.text.strip())

        fallback_elem = encode_elem.find("fallback")
        if fallback_elem is not None:
            for child in fallback_elem:
                if child.text and child.text.strip():
                    fallback[child.tag] = child.text.strip()

        filters_elem = encode_elem.find("filters")
        if filters_elem is not None:
            for child in filters_elem:
                if child.text and child.text.strip():
                    filters[child.tag] = child.text.strip()

    # --- Audio ---
    audio = {"stereo": {}, "multi_channel": {}}
    stereo_elem = root.find("audio/stereo")
    if stereo_elem is not None:
        for child in stereo_elem:
            if child.text and child.text.strip():
                audio["stereo"][child.tag] = int(child.text.strip())

    multi_elem = root.find("audio/multi_channel")
    if multi_elem is not None:
        for child in multi_elem:
            if child.text and child.text.strip():
                audio["multi_channel"][child.tag] = int(child.text.strip())

    # --- Services (Sonarr/Radarr) ---
    services = {"sonarr": {}, "radarr": {}}
    sonarr_elem = root.find("services/sonarr")
    if sonarr_elem is not None:
        url_elem = sonarr_elem.find("url")
        api_elem = sonarr_elem.find("api_key")
        rg_elem = sonarr_elem.find("new_release_group")
        services["sonarr"] = {
            "url": url_elem.text if url_elem is not None and url_elem.text else None,
            "api_key": api_elem.text if api_elem is not None and api_elem.text else None,
            "new_release_group": rg_elem.text if rg_elem is not None and rg_elem.text else "CONVERTED"
        }
    
    radarr_elem = root.find("services/radarr")
    if radarr_elem is not None:
        url_elem = radarr_elem.find("url")
        api_elem = radarr_elem.find("api_key")
        rg_elem = radarr_elem.find("new_release_group")
        services["radarr"] = {
            "url": url_elem.text if url_elem is not None and url_elem.text else None,
            "api_key": api_elem.text if api_elem is not None and api_elem.text else None,
            "new_release_group": rg_elem.text if rg_elem is not None and rg_elem.text else "CONVERTED"
        }

    return {
        "processing_folder": processing_folder,
        "suffix": suffix,
        "extensions": [ext.lower() for ext in extensions],
        "ignore_tags": [tag.strip() for tag in ignore_tags],
        "reduction_ratio_threshold": reduction_ratio_threshold,
        "path_mappings": path_mappings,
        "general": general_dict,
        "encode": {"cq": cq, "fallback": fallback, "filters": filters},
        "audio": audio,
        "services": services
    }
