import json
from datetime import datetime

from data.sig_ref import SIGRef
from data.spot import Spot
from providers.spot.sse_spot_provider import SSESpotProvider


class WWBOTA(SSESpotProvider):
    """Spot provider for Worldwide Bunkers on the Air"""

    SPOTS_URL = "https://api.wwbota.net/spots/"

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

    def _sse_message_to_spot(self, message_data):
        source_spot = json.loads(message_data)
        # Convert to our spot format. First we unpack references, because WWBOTA spots can have more than one for
        # n-fer activations.
        refs = []
        for ref in source_spot["references"]:
            sigref = SIGRef(id=ref["reference"], sig="WWBOTA", name=ref["name"], latitude=ref["lat"],
                            longitude=ref["long"])
            refs.append(sigref)

        spot = Spot(source=self.name,
                    dx_call=source_spot["call"].upper(),
                    de_call=source_spot["spotter"].upper(),
                    freq=float(source_spot["freq"]) * 1000000,
                    mode=source_spot["mode"].upper(),
                    comment=source_spot["comment"],
                    sig="WWBOTA",
                    sig_refs=refs,
                    time=datetime.fromisoformat(source_spot["time"].replace("Z", "+00:00")).timestamp(),
                    # WWBOTA spots can contain multiple references for bunkers being activated simultaneously. For
                    # now, we will just pick the first one to use as our grid, latitude and longitude.
                    dx_grid=source_spot["references"][0]["locator"],
                    dx_latitude=source_spot["references"][0]["lat"],
                    dx_longitude=source_spot["references"][0]["long"],
                    qrt=source_spot["type"] == "QRT")

        # WWBOTA does support a special "Test" spot type, we need to avoid adding that.
        return spot if source_spot["type"] != "Test" else None

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

    def submit_spot(self, spot, credentials):
        # TODO: Implement. WWBOTA API docs cover this: https://api.wwbota.org/#tag/Spots/operation/create_spot_spots__post
        raise NotImplementedError("WWBOTA upstream spot submission is not yet implemented")
