from bs4 import BeautifulSoup
from uk_bin_collection.uk_bin_collection.common import *
from uk_bin_collection.uk_bin_collection.get_bin_data import AbstractGetBinDataClass
from lxml import etree


# import the wonderful Beautiful Soup and the URL grabber
class CouncilClass(AbstractGetBinDataClass):
    """
    Concrete classes have to implement all abstract operations of the
    base class. They can also override some operations with a default
    implementation.
    """

    def parse_data(self, page: str, **kwargs) -> dict:
        # Make a BS4 object
        soup = BeautifulSoup(page.text, features="lxml")
        soup.prettify()
        data = {"bins": []}
        collections = []

        # Convert the XML to JSON and load the next collection data
        result = soup.find("p").contents[0].text.replace("\\", "")[1:-1]
        json_data = json.loads(result)["NextCollection"]

        # Get general waste data
        if json_data.get("RefuseCollectionBinDate") is not None:
            bin_type = "Green general waste bin"
            if json_data.get("RefuseBinExceptionMessage") != "":
                bin_type += f" ({json_data.get('RefuseBinExceptionMessage')})".rstrip()
            bin_date = datetime.strptime(
                json_data.get("RefuseCollectionBinDate"), "%Y-%m-%dT%H:%M:%S"
            )
            collections.append((bin_type, bin_date))

        # Get recycling waste data
        if json_data.get("RecyclingCollectionDate") is not None:
            bin_type = "Blue recycling bin"
            if json_data.get("RecyclingExceptionMessage") != "":
                bin_type += f" ({json_data.get('RecyclingExceptionMessage')})".rstrip()
            bin_date = datetime.strptime(
                json_data.get("RecyclingCollectionDate"), "%Y-%m-%dT%H:%M:%S"
            )
            collections.append((bin_type, bin_date))

        # Get garden waste data
        if json_data.get("GardenWasteCollectionDate") is not None:
            bin_type = "Brown garden waste bin"
            if json_data.get("GardenWasteExceptionMessage") != "":
                bin_type += (
                    f" ({json_data.get('GardenWasteExceptionMessage')})".rstrip()
                )
            bin_date = datetime.strptime(
                json_data.get("GardenWasteCollectionDate"), "%Y-%m-%dT%H:%M:%S"
            )
            collections.append((bin_type, bin_date))

        # Get food waste data
        if json_data.get("FoodWasteCollectionDate") is not None:
            bin_type = "Black food waste bin"
            if json_data.get("FoodWasteExceptionMessage") != "":
                bin_type += f" ({json_data.get('FoodWasteExceptionMessage')})".rstrip()
            bin_date = datetime.strptime(
                json_data.get("FoodWasteCollectionDate"), "%Y-%m-%dT%H:%M:%S"
            )
            collections.append((bin_type, bin_date))

        # If there's no collections, raise an error
        if len(collections) < 1:
            raise ValueError("No collections found")

        # Order the collection by date, then return them
        ordered_data = sorted(collections, key=lambda x: x[1])
        for bin in ordered_data:
            dict_data = {
                "type": bin[0],
                "collectionDate": bin[1].strftime(date_format),
            }
            data["bins"].append(dict_data)

        return data
