from ..extractor import *
import json
import dateutil.parser
from datetime import datetime, timezone
import requests
from urllib.parse import urlparse
from bs4 import BeautifulSoup

import logging

logger = logging.getLogger(__name__)

# A class dedicated to get events from les amis du temps des cerises
# Website https://amisdutempsdescerises.org/
class CExtractor(Extractor):

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

    # Source code adapted from https://framagit.org/Marc-AntoineA/mobilizon-client-python
    def _request(self, body, data):

            headers = {}

            response = requests.post(url=self._api_end_point, json={ "query": body, "variables": data }, headers=headers)

            if response.status_code == 200:
                response_json = response.json()
                if 'errors' in response_json:
                    raise Exception(f'Errors while requesting { body }. { str(response_json["errors"]) }')

                return response_json['data']
            else:
                raise Exception(f'Error while requesting. Status code: { response.status_code }')

    def _oncoming_events_number(self):

        query = '''
query($preferredUsername: String!, $afterDatetime: DateTime) {
    group(preferredUsername: $preferredUsername) {
        organizedEvents(afterDatetime: $afterDatetime) {
            total,
        }
    }
}
        '''
        today = datetime.now(timezone.utc).isoformat()
        data = {
            'preferredUsername': self._group_id,
            'afterDatetime': today
        }
        r = self._request(query, data)
        return r['group']['organizedEvents']['total']


    def _oncoming_events(self):
        def _oncoming_events_page(page):
            query = '''
query($preferredUsername: String!, $afterDatetime: DateTime, $page: Int) {
    group(preferredUsername: $preferredUsername) {
        organizedEvents(afterDatetime: $afterDatetime, page: $page) {
            elements {
                id,
                title,
                url,
                beginsOn,
                endsOn,
                options {
                showStartTime,
                showEndTime,
                timezone
                },
                attributedTo {
                avatar {
                    url,
                }
                name,
                preferredUsername,
                },
                description,
                onlineAddress,
                physicalAddress {
                locality,
                description,
                region
                },
                tags {
                title,
                id,
                slug
                },
                picture {
                url
                },
                status
            }
        }
    }
}
        '''

            today = datetime.now(timezone.utc).isoformat()
            data = {
                'preferredUsername': self._group_id,
                'afterDatetime': today,
                'page': page
            }
            r = self._request(query, data)
            return r['group']['organizedEvents']['elements']

        number_events = self._oncoming_events_number()

        events = []
        page = 1
        while len(events) < number_events:
            events.extend(_oncoming_events_page(page))
            page += 1
        return events

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

        if "@" in url:

            # TODO: quand on a
            # https://mobilizon.fr/@xr_clermont_ferrand@mobilizon.extinctionrebellion.fr/events
            # on doit retourner :
            # https://mobilizon.extinctionrebellion.fr/@xr_clermont_ferrand/events

            # split url to identify server url and actor id
            elems = [x for x in url.split('/') if len(x) > 0 and x[0] == "@"]
            if len(elems) == 1:
                params = elems[0].split('@')
                if len(params) == 2:
                    self._api_end_point = "https://" + urlparse(url).netloc + "/api"
                    self._group_id = params[1]
                else:
                    self._api_end_point = "https://" + params[2] + "/api"
                    self._group_id = params[1]

                events = self._oncoming_events()


                for e in events:
                    title = e["title"]
                    event_url = e["url"]
                    image = e["picture"]["url"]
                    location = e["physicalAddress"]["description"] + ', ' + e["physicalAddress"]["locality"]
                    soup = BeautifulSoup(e["description"], "html.parser")
                    
                    description = soup.text
                    start = dateutil.parser.isoparse(e["beginsOn"]).replace(tzinfo=timezone.utc).astimezone(tz=None)
                    end = dateutil.parser.isoparse(e["endsOn"]).replace(tzinfo=timezone.utc).astimezone(tz=None)

                    start_day = start.date()
                    start_time = start.time() if e["options"]["showStartTime"] else None
                    end_day = end.date()
                    end_time = end.time() if e["options"]["showEndTime"] else None


                    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,
                        end_day=end_day,
                        end_time=end_time)
        
        return self.get_structure()
