import logging
import re
from datetime import datetime
from typing import cast

import pytz
from rss_parser import Parser
from rss_parser.models.rss import RSS

from data.sig_ref import SIGRef
from data.spot import Spot
from providers.spot.http_spot_provider import HTTPSpotProvider


class WOTA(HTTPSpotProvider):
    """Spot provider for Wainwrights on the Air"""

    POLL_INTERVAL_SEC = 120
    SPOTS_URL = "https://www.wota.org.uk/spots_rss.php"
    LIST_URL = "https://www.wota.org.uk/mapping/data/summits.json"
    RSS_DATE_TIME_FORMAT = "%a, %d %b %Y %H:%M:%S %z"

    def __init__(self, provider_config):
        super().__init__("WOTA", provider_config, self.SPOTS_URL, self.POLL_INTERVAL_SEC)

    def _http_response_to_spots(self, http_response):
        new_spots = []
        rss = cast(RSS, Parser.parse(http_response.content.decode("utf-8-sig")))
        # Iterate through source data
        for source_spot in rss.channel.items:

            try:
                # Reject GUID missing or zero
                if not source_spot.guid or not source_spot.guid.content or source_spot.guid.content == "http://www.wota.org.uk/spots/0":
                    continue

                # Pick apart the title
                title_split = source_spot.title.split(" on ")
                dx_call = title_split[0]
                ref = None
                ref_name = None
                if len(title_split) > 1:
                    ref_split = title_split[1].split(" - ")
                    ref = str(ref_split[0])
                    if len(ref_split) > 1:
                        ref_name = str(ref_split[1])

                # Pick apart the description
                desc_split = source_spot.description.split(". ")
                freq_mode = desc_split[0].replace("Frequencies/modes:", "").strip()
                freq_mode_split = re.split(r'[\-\s]+', freq_mode)
                freq_hz = float(freq_mode_split[0].replace("'", ".")) * 1000000
                mode = None
                if len(freq_mode_split) > 1:
                    mode = freq_mode_split[1].upper()

                comment = None
                if len(desc_split) > 1:
                    comment = desc_split[1].strip()
                spotter = None
                if len(desc_split) > 2:
                    spotter = desc_split[2].replace("Spotted by ", "").replace(".", "").upper().strip()

                time = datetime.strptime(source_spot.pub_date.content, self.RSS_DATE_TIME_FORMAT).astimezone(pytz.UTC)

                # Convert to our spot format
                spot = Spot(source=self.name,
                            source_id=source_spot.guid.content,
                            dx_call=dx_call,
                            de_call=spotter,
                            freq=freq_hz,
                            mode=mode,
                            comment=comment,
                            sig="WOTA",
                            sig_refs=[SIGRef(id=ref, sig="WOTA", name=ref_name)] if ref else [],
                            time=time.timestamp())

                new_spots.append(spot)
            except Exception as e:
                logging.error("Exception parsing WOTA spot", e)
        return new_spots

    def can_submit_spot(self, sig):
        return sig == "WOTA"

    def submit_spot(self, spot, credentials):
        # TODO Ask M5TEA if he's happy to share how this is done from his app
        raise NotImplementedError("WOTA upstream spot submission is not yet implemented")
