from datetime import datetime
from bs4 import BeautifulSoup
from urllib.parse import urlparse

from ..extractor import *
from ..twosteps_extractor import *

import json

import logging

logger = logging.getLogger(__name__)

class GGCalendar:
    def __init__(self, url):
        self.url = url
        self.extract_info()

    def filter_keys(params):
        result = {}

        for k, v in params.items():
            if k.startswith('e[0]'):
                result[k.replace('e[0][', '')[:-1]] = v
            else:
                result[k] = v

        return result

    def is_valid_event(self):
        return self.start_day is not None and self.title is not None

    def extract_info(self):
        parsed_url = urlparse(self.url.replace("#", "%23"))
        params = parse_qs(parsed_url.query)

        params = GGCalendar.filter_keys(params)

        self.location = params["location"][0] if "location" in params else ""
        self.title = params["text"][0] if "text" in params else params["title"][0] if "title" in params else ""
        self.description = params["description"][0] if "description" in params else params["details"][0] if "details" in params else ""
        if self.description != "":
            self.description = BeautifulSoup(self.description, "html.parser").text
        if "dates" in params:
            dates = [x.replace(" ", "+") for x in params["dates"][0].split("/")]
            if len(dates) > 0:
                date = parser.parse(dates[0])
                self.start_day = date.date()
                self.start_time = date.time()
                if len(dates) == 2:
                    date = parser.parse(dates[1])
                    self.end_day = date.date()
                    self.end_time = date.time()
                else:
                    self.end_day = None
                    self.end_time = None
        elif "date_start" in params:
            date = parser.parse(params["date_start"][0])
            self.start_day = date.date()
            self.start_time = date.time()
            if "date_end" in params:
                dateend = parser.parse(params["date_end"][0])
                if dateend != date:
                    self.end_day = dateend.date()
                    self.end_time = dateend.time()
                else:
                    self.end_day = None
                    self.end_time = None
                    if self.start_time == datetime.time(0):
                        self.start_time = None

            else:
                self.end_day = None
                self.end_time = None
        else:
            raise Exception("Unable to find a date in google calendar URL")
            self.start_day = None
            self.start_time = None
            self.end_day = None
            self.end_time = None



class CExtractor(Extractor):
    def __init__(self):
        super().__init__()
        self.possible_urls = ["https://calendar.google.com/calendar/", "https://addtocalendar.com/", "https://www.google.com/calendar/event"]


    def guess_image(self, soup, url):
        image = soup.find("meta", property="og:image")

        if image is None:
            for img in soup.select('img'):
                if img.find_parent(name='nav'):
                    continue
                image = img["src"]
                break
        else:
            image = image["content"]

        if image.startswith("/"):
            root_url = "https://" + urlparse(url).netloc + "/"
            image = root_url + image

        return image


    def extract(
        self, content, url, url_human=None, default_values=None, published=False
    ):
        soup = BeautifulSoup(content, "html.parser")

        for ggu in self.possible_urls:

            link_calendar = soup.select('a[href^="' + ggu + '"]')
            if len(link_calendar) != 0:

                gg_cal = GGCalendar(link_calendar[0]["href"])

                if gg_cal.is_valid_event():
                    start_day = gg_cal.start_day
                    start_time = gg_cal.start_time
                    description = gg_cal.description.replace('&nbsp;', '')
                    end_day = gg_cal.end_day
                    end_time = gg_cal.end_time
                    location = gg_cal.location
                    title = gg_cal.title
                    url_human = url

                    self.set_header(url)

                    image = self.guess_image(soup, url)

                    category = None

                    self.add_event(
                        default_values,
                        title=title,
                        category=category,
                        start_day=start_day,
                        location=location,
                        description=description,
                        tags=[],
                        uuids=[url],
                        recurrences=None,
                        url_human=url_human,
                        start_time=start_time,
                        end_day=end_day,
                        end_time=end_time,
                        published=published,
                        image=image,
                    )

                    break


        return self.get_structure()