import re
import urllib.request
import unicodedata
import xml.etree.ElementTree as ET

TVG_URL = "https://epg-sw.duckdns.org/sledovani.xml"

INPUT_M3U = "/opt/epg/LiveTV.m3u"
OUTPUT_M3U = "/opt/epg/playlist_epg.m3u"
NOT_FOUND_FILE = "/opt/epg/not_found.txt"


def normalize(name):
    name = name.strip().upper()

    # odstránenie diakritiky
    name = unicodedata.normalize("NFKD", name)
    name = "".join(
        c for c in name
        if not unicodedata.combining(c)
    )

    # odstránenie špeciálnych znakov
    name = re.sub(r"[^A-Z0-9+]", "", name)

    return name


# ============================================================
# ALIASY: tvg-name z playlistu -> channel id zo SledovanieTV
# ============================================================

ALIASES = {

    # Slovenské hlavné kanály
    "JEDNOTKA": "stv1",
    "DVOJKA": "stv2",
    "RTVS :24": "stv4",
    "TA3 ": "ta3",
    "DOMA": "doma",
    "DAJTO": "dajto",

    "MARKIZA": "markiza",
    "MARKIZA+1": "markiza",
    "MARKIZA KRIMI": "markiza_krimi",
    "MARKIZA KLASIK": "markiza_klasik",
    "MARKIZA INTERNATIONAL": "markizaint",
    "TV JOJ 24": "joj_24",          
    "JOJ": "joj",
    "JOJ KRIMI": "wau",
    "JOJ SVET": "joj_svet",
    "JOJ PLUS": "jojplus",
    "JOJ FAMILY": "jojfamily",
    "JOJ CINEMA": "jojcinema",
    "JOJ ŠPORT": "joj_sport",
    "JOJ SPORT 2": "joj_sport2",
    "WARNER TV": "warner_tv",
    "TELEVIZE SEZNAM": "Seznam",
 
    # Česká televize
    "ČT1": "ct1",
    "ČT2": "ct2",
    "CT1": "ct1",
    "CT2": "ct2",
    "CT 24": "ct24",
    "ČT SPORT": "ct4sport",
    "CT:D": "ctdecko",
    "CT:D/CT ART": "ctart",

    # Nova
    "NOVA TV": "nova",
    "NOVA LADY": "nova_lady",
    "NOVA CINEMA": "novacinema",
    "NOVA KRIMI": "smichov",
    "NOVA ACTION": "telka",
    "NOVA FUN": "fanda",
    "NOVA SPORT 1": "nova_sport",
    "NOVA SPORT 2": "nova_sport2",
    "NOVA INTERNATIONAL": "novaint",
 
    # Prima
    "PRIMA TV CZ": "primafamily",
    "PRIMA TV SK": "primaplus",

    "PRIMA COOL CZ": "primacool",
    "PRIMA COOL SK": "primacool_sk",

    "PRIMA STAR": "prima_star",
    "PRIMA SHOW": "prima_show",

    "PRIMA LOVE CZ": "primalove",
    "PRIMA LOVE SK": "prima_love_sk",

    "PRIMA KRIMI CZ": "prima_krimi",
    "PRIMA KRIMI SK": "prima_krimi_sk",

    "PRIMA MAX": "prima_max",
    "PRIMA ZOOM": "primazoom",

    # Film
    "FILM+": "film_plus",
    "FILMBOX": "filmbox",
    "FILMBOX EXTRA": "FilmboxExtra",
    "FILMBOX FAMILY": "FilmboxFamily",
    "FILMBOX ARTHOUSE": "FilmboxArthouse",
    "FILM EUROPE": "Film_Europe",
    "+FILM EUROPE": "Film_Europe",
    "FILMPRO": "filmpro",

    # AXN
    "AXN": "axn",
    "AXN BLACK": "axnblack",
    "AXN WHITE": "axnwhite",

    "EPIC DRAMA": "epic_drama",

    # Barrandov
    "TV BARRANDOV": "barrandov",
    "KINO BARRANDOV": "kinobarrandov",

    # HBO / Cinemax
    "HBO": "HBO",
    "HBO2": "HBO2",
    "CINEMAX": "cinemax1",
    "CINEMAX 2": "cinemax2",

    # Dokumentárne
    "DISCOVERY": "Discovery",
    "ID": "ID",
    "BBC EARTH": "bbc_earth",

    "HISTORY CHANNEL": "history",
    "SPEKTRUM": "spektrum",
    "SPEKTRUM HOME": "spektrum_home",

    "VIASAT HISTORY": "viasat_history",
    "VIASAT NATURE": "viasat_nature",
    "VIASAT EXPLORE": "viasat_explore",

    "NATIONAL GEOGRAPHIC": "NGC_HD",
    "NATIONAL GEOGRAPHIC WILD": "nat_geo_wild",
    "ANIMAL PLANET": "animal_planet",

    "TLC": "TLC",
    "LOVE NATURE": "love_nature",

    "TRAVEL CHANNEL": "travelhd",
    "TRAVEL XP": "travelxp",

    "FISHING & HUNTING": "fishinghunting",
    "TV PAPRIKA": "tv_paprika",
    "HGTV": "hgtv_ce",

    # Hudba / zábava
    "MEZZO": "mezzo",
    "MEZZO LIVE": "mezzo_live",
    "MTV": "mtv",

    # Detské
    "JIM JAM": "Jim_Jam",
    "NICKELDEON": "Nickelodeon",
    "NICK JR.": "nickjr",
    "NICKTOONS": "nicktoons",
    "MINIMAX": "Minimax",

    "LALA TV": "lala_tv",
    "RIK": "rik",
    "DUCK TV": "ducktv_cz",

    "DISNEY CHANNEL": "Disney_Channel",
    "DISNEY JUNIOR": "disney_junior",

    "CARTOON NETWORK": "cartoon_network_hd",
    "BABY TV": "baby_tv",

    # Správy
    "TA3": "ta3",
    "TV JOJ 24": "joj_24",
    "BBC NEWS": "bbc",
    "SKY NEWS": "sky_news",
    "FRANCE 24 (ENGLISH)": "france24",
    "TV5 MONDE": "tv5",

    # Šport
    "EUROSPORT 1": "Eurosport",
    "EUROSPORT 2": "Eurosport2",
    "GOLF CHANNEL": "golf",

    # Ostatné
    "TV LUX": "tv_lux",
    "TV NOE": "tvnoe",
    "NOE+ TV": "NoePlus",
    "DVTV": "DVTV",
    "SEZNAM": "Seznam",
}


# ============================================================
# NAČÍTANIE EPG
# ============================================================

print("Downloading EPG...")

xml_data = urllib.request.urlopen(TVG_URL).read()

root = ET.fromstring(xml_data)

epg_channels = {}

for channel in root.findall("channel"):

    channel_id = channel.get("id")
    display_name = channel.findtext("display-name")

    if not channel_id or not display_name:
        continue

    epg_channels[normalize(display_name)] = channel_id


print(f"Loaded {len(epg_channels)} channels from EPG.")


# ============================================================
# NAČÍTANIE PLAYLISTU
# ============================================================

with open(INPUT_M3U, encoding="utf-8", errors="ignore") as f:
    lines = f.readlines()


output = []

matched = 0
not_found = 0
already_had_id = 0

not_found_names = set()


# ============================================================
# SPRACOVANIE
# ============================================================

for line in lines:

    if not line.startswith("#EXTINF"):
        output.append(line)
        continue

    # --------------------------------------------------------
    # nájdi tvg-name
    # --------------------------------------------------------

    match = re.search(r'tvg-name="([^"]*)"', line)

    if not match:

        output.append(line)
        continue

    tvg_name = match.group(1).strip()

    normalized_name = normalize(tvg_name)

    channel_id = None

    # --------------------------------------------------------
    # 1. najprv alias
    # --------------------------------------------------------

    if normalized_name in {
        normalize(k): v
        for k, v in ALIASES.items()
    }:
        alias_map = {
            normalize(k): v
            for k, v in ALIASES.items()
        }

        channel_id = alias_map[normalized_name]

    # --------------------------------------------------------
    # 2. potom presná zhoda s EPG
    # --------------------------------------------------------

    elif normalized_name in epg_channels:

        channel_id = epg_channels[normalized_name]

    # --------------------------------------------------------
    # NAŠLI SME
    # --------------------------------------------------------

    if channel_id:

        if 'tvg-id="' in line:

            line = re.sub(
                r'tvg-id="[^"]*"',
                f'tvg-id="{channel_id}"',
                line
            )

        else:

            line = line.replace(
                "#EXTINF:-1",
                f'#EXTINF:-1 tvg-id="{channel_id}"',
                1
            )

        matched += 1

        print(
            f"OK       {tvg_name:<35} -> {channel_id}"
        )

    # --------------------------------------------------------
    # NENAŠLI SME
    # --------------------------------------------------------

    else:

        not_found += 1
        not_found_names.add(tvg_name)

        print(
            f"NO EPG   {tvg_name}"
        )

    output.append(line)


# ============================================================
# ULOŽENIE
# ============================================================

with open(OUTPUT_M3U, "w", encoding="utf-8") as f:
    f.writelines(output)


# ============================================================
# NENÁJDENÉ KANÁLY
# ============================================================

with open(NOT_FOUND_FILE, "w", encoding="utf-8") as f:

    for name in sorted(not_found_names, key=str.lower):
        f.write(name + "\n")


print()
print("==========================================")
print("FINISHED")
print("==========================================")
print(f"Matched:   {matched}")
print(f"Not found: {not_found}")
print(f"Output:    {OUTPUT_M3U}")
print(f"Unknown:   {NOT_FOUND_FILE}")
print("==========================================")