import urllib.request
from html.parser import HTMLParser
import xml.etree.ElementTree as ET
from xml.dom import minidom
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
from urllib.parse import quote


# ==========================================
# NASTAVENIE
# ==========================================

START_DATE = datetime.now().date()

DAYS = 3

OUTPUT = "/opt/epg/sledovani.xml"

TIMEZONE = ZoneInfo("Europe/Prague")


CHANNELS = [
    ("fast_epg_kids", "Starmax kids"),
    ("dog_cat", "Dog Cat"),
    ("fast_epg_family", "Starmax Family"),
    ("fast_epg_czsk", "Starmax CZ&SK"),
    ("fast_epg_comedy", "Starmax Comedy"),
    ("ballcasterz", "Ballcasterz"),
    ("DVTV", "DVTV"),
    ("tv_romana", "tv_romana"),
    ("naturetv", "Nature TV"),
    ("filmpro", "FilmPRO"),
    ("tv_lux", "tv_lux"),
    ("tvnoe", "tvnoe"),
    ("NoePlus", "NoePlus"),

]


# ==========================================
# HTML PARSER
# ==========================================

class EPGParser(HTMLParser):

    def __init__(self, channel_id):
        super().__init__()

        self.channel_id = channel_id

        self.programmes = []

        self.current_time = None
        self.current_title = None

        self.in_li = False
        self.in_a = False

    def handle_starttag(self, tag, attrs):

        attrs = dict(attrs)

        if tag == "li":

            self.in_li = True

            self.current_time = None
            self.current_title = None

        if self.in_li and tag == "span":

            data_time = attrs.get("data-time")

            if data_time:

                try:
                    self.current_time = int(data_time)
                except ValueError:
                    pass

        if self.in_li and tag == "a":

            href = attrs.get("href", "")

            if "channelEvent:" + self.channel_id + ":" in href:

                self.in_a = True

    def handle_data(self, data):

        if self.in_a:

            text = data.strip()

            if text:

                if self.current_title:

                    self.current_title += " " + text

                else:

                    self.current_title = text

    def handle_endtag(self, tag):

        if tag == "a":

            self.in_a = False

        if tag == "li":

            if self.current_time and self.current_title:

                self.programmes.append({
                    "start": self.current_time,
                    "title": self.current_title
                })

            self.in_li = False


# ==========================================
# XMLTV
# ==========================================

tv = ET.Element("tv")

tv.set(
    "generator-info-name",
    "SledovaniTV"
)


total_channels = 0
total_programmes = 0


# ==========================================
# CHANNELS
# ==========================================

for channel_id, channel_name in CHANNELS:

    print()
    print("==========================================")
    print("KANÁL:", channel_name)
    print("ID:", channel_id)
    print("==========================================")


    # --------------------------------------
    # CHANNEL
    # --------------------------------------

    channel = ET.SubElement(
        tv,
        "channel"
    )

    channel.set(
        "id",
        channel_id
    )

    display_name = ET.SubElement(
        channel,
        "display-name"
    )

    display_name.text = channel_name

    total_channels += 1


    # --------------------------------------
    # DNI
    # --------------------------------------

    for day_offset in range(DAYS):

        current_date = START_DATE + timedelta(
            days=day_offset
        )

        date_string = current_date.strftime(
            "%Y-%m-%d"
        )

        print()
        print("Dátum:", date_string)


        url = (
            "https://sledovanitv.cz/epg/default/"
            + date_string
            + "?channel=channel%3A"
            + quote(channel_id)
        )

        print("Sťahujem...")


        try:

            req = urllib.request.Request(
                url,
                headers={
                    "User-Agent": "Mozilla/5.0"
                }
            )

            with urllib.request.urlopen(
                req,
                timeout=30
            ) as response:

                html = response.read().decode(
                    "utf-8"
                )

        except Exception as e:

            print("CHYBA:", e)

            continue


        parser = EPGParser(
            channel_id
        )

        parser.feed(html)

        programmes = parser.programmes


        # ----------------------------------
        # ODSTRÁNENIE DUPLÍC
        # ----------------------------------

        unique = {}

        for p in programmes:

            key = (
                p["start"],
                p["title"]
            )

            if key not in unique:

                unique[key] = p


        programmes = list(
            unique.values()
        )


        programmes.sort(
            key=lambda x: x["start"]
        )


        print(
            "Nájdené programy:",
            len(programmes)
        )


        # ----------------------------------
        # PROGRAMMES
        # ----------------------------------

        for i, program in enumerate(
            programmes
        ):

            start_timestamp = program[
                "start"
            ]


            start_dt = datetime.fromtimestamp(
                start_timestamp,
                tz=TIMEZONE
            )


            # Koniec programu =
            # začiatok ďalšieho programu

            if i + 1 < len(programmes):

                end_timestamp = programmes[
                    i + 1
                ]["start"]

                end_dt = datetime.fromtimestamp(
                    end_timestamp,
                    tz=TIMEZONE
                )

            else:

                # Posledný program dňa
                # zatiaľ +1 hodina

                end_dt = (
                    start_dt
                    + timedelta(hours=1)
                )


            start_xml = start_dt.strftime(
                "%Y%m%d%H%M%S %z"
            )

            end_xml = end_dt.strftime(
                "%Y%m%d%H%M%S %z"
            )


            programme = ET.SubElement(
                tv,
                "programme"
            )

            programme.set(
                "start",
                start_xml
            )

            programme.set(
                "stop",
                end_xml
            )

            programme.set(
                "channel",
                channel_id
            )


            title = ET.SubElement(
                programme,
                "title"
            )

            title.set(
                "lang",
                "cs"
            )

            title.text = program[
                "title"
            ]


            total_programmes += 1


# ==========================================
# ULOŽENIE XML
# ==========================================

xml_data = ET.tostring(
    tv,
    encoding="utf-8"
)


pretty = minidom.parseString(
    xml_data
).toprettyxml(
    indent="    ",
    encoding="UTF-8"
)


with open(
    OUTPUT,
    "wb"
) as f:

    f.write(pretty)


# ==========================================
# VÝSLEDOK
# ==========================================

print()
print()
print("==========================================")
print(" SLEDOVANITV XMLTV – 3 DNI")
print("==========================================")
print("Od:       ", START_DATE)
print("Počet dní:", DAYS)
print("Kanály:   ", total_channels)
print("Programy: ", total_programmes)
print("Výstup:   ", OUTPUT)
print("==========================================")
print()

