import logging
from django.conf import settings
import dateutil.parser
import requests
import re
import json

from ..extractor import Extractor

logger = logging.getLogger(__name__)


# A class dedicated to get events from helloasso
class CExtractor(Extractor):
    patternEvent = (
        r"^https://www\.helloasso\.com/associations/([\w\-]+)/evenements/([\w\-]+)"
    )
    patternOrg = r"^https://www\.helloasso\.com/associations/([\w\-]+)"

    urlAPI = "https://api.helloasso.com"

    def __init__(self):
        super().__init__()
        self.no_downloader = True

    def id_and_secret_available(self):
        return settings.HELLOASSO_ID != "" and settings.HELLOASSO_SECRET != ""

    def is_known_url(url):
        return (
            re.match(CExtractor.patternEvent, url) is not None
            or re.match(CExtractor.patternOrg, url) is not None
        )

    def get_header_with_token():
        url = CExtractor.urlAPI + "/oauth2/token"

        payload = {
            "grant_type": "client_credentials",
            "client_id": settings.HELLOASSO_ID,
            "client_secret": settings.HELLOASSO_SECRET,
        }
        headers = {
            "accept": "application/json",
            "Content-Type": "application/x-www-form-urlencoded",
        }

        response = requests.post(url, data=payload, headers=headers)

        data = json.loads(response.text)

        return {
            "accept": "application/json",
            "authorization": "Bearer " + data["access_token"],
        }

    def _get_single_event(org, event, headers=None):
        if headers is None:
            headers = CExtractor.get_header_with_token()
        url = CExtractor.urlAPI + "/v5/organizations/{}/forms/Event/{}/public".format(
            org, event
        )
        response = requests.get(url, headers=headers)
        return json.loads(response.text)

    def _get_all_events(org):
        url = (
            CExtractor.urlAPI
            + "/v5/organizations/{}/forms?states=Public&formTypes=Event&pageSize=20".format(
                org
            )
        )
        headers = CExtractor.get_header_with_token()
        result = []
        for i in range(1, 200):
            response = requests.get(url + "&pageIndex={}".format(i), headers=headers)
            events = json.loads(response.text)["data"]
            if len(events) == 0:
                return result
            else:
                for e in events:
                    result.append(
                        CExtractor._get_single_event(org, e["formSlug"], headers)
                    )

    def _get_events(self, url):
        match = re.match(CExtractor.patternEvent, url)
        if match:
            return [CExtractor._get_single_event(match.group(1), match.group(2))]
        else:
            match = re.match(CExtractor.patternOrg, url)
            if match:
                return CExtractor._get_all_events(match.group(1))

        return []

    def extract(
        self,
        content,
        url,
        url_human=None,
        default_values=None,
        published=False,
    ):

        self.set_header(url)
        self.clear_events()

        if not self.id_and_secret_available():
            logger.error("ID/Secret not available")
            raise Exception("ID/Secret not available")

        if not CExtractor.is_known_url(url):
            logger.error("Unknown url")
            raise Exception("Unknown url")

        events = self._get_events(url)

        for event in events:
            title = event["title"]
            event_url = event["url"]

            image = None
            image_alt = None
            if "banner" in event:
                image = event["banner"]["publicUrl"]
                if "description" in event["banner"]:
                    image_alt = event["banner"]["description"]

            location = []
            if "place" in event and event["place"] is not None:
                for elplace in ["name", "address", "zipCode", "city"]:
                    if elplace in event["place"]:
                        location.append(event["place"][elplace])
            location = ", ".join(location)

            description = event["description"]

            start = dateutil.parser.isoparse(event["startDate"])
            end = dateutil.parser.isoparse(event["endDate"])

            start_day = start.date()
            start_time = start.time()
            end_day = end.date()
            end_time = end.time()

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

        return self.get_structure()
