"""Calendar service."""
from calendar import monthrange
from datetime import datetime

from tzlocal import get_localzone


class CalendarService:
    """
    The 'Calendar' iCloud service, connects to iCloud and returns events.
    """

    def __init__(self, service_root, session, params):
        self.session = session
        self.params = params
        self._service_root = service_root
        self._calendar_endpoint = f"{self._service_root}/ca"
        self._calendar_refresh_url = f"{self._calendar_endpoint}/events"
        self._calendar_event_detail_url = f"{self._calendar_endpoint}/eventdetail"
        self._calendars = f"{self._calendar_endpoint}/startup"

        self.response = {}

    def get_event_detail(self, pguid, guid):
        """
        Fetches a single event's details by specifying a pguid
        (a calendar) and a guid (an event's ID).
        """
        params = dict(self.params)
        params.update(
            {
                "lang": "en-us",
                "usertz": get_localzone().zone,
                "dsid": self.session.service.data["dsInfo"]["dsid"],
            }
        )
        url = f"{self._calendar_event_detail_url}/{pguid}/{guid}"
        req = self.session.get(url, params=params)
        self.response = req.json()
        return self.response["Event"][0]

    def refresh_client(self, from_dt=None, to_dt=None):
        """
        Refreshes the CalendarService endpoint, ensuring that the
        event data is up-to-date. If no 'from_dt' or 'to_dt' datetimes
        have been given, the range becomes this month.
        """
        today = datetime.today()
        first_day, last_day = monthrange(today.year, today.month)
        if not from_dt:
            from_dt = datetime(today.year, today.month, first_day)
        if not to_dt:
            to_dt = datetime(today.year, today.month, last_day)
        params = dict(self.params)
        params.update(
            {
                "lang": "en-us",
                "usertz": get_localzone().zone,
                "startDate": from_dt.strftime("%Y-%m-%d"),
                "endDate": to_dt.strftime("%Y-%m-%d"),
                "dsid": self.session.service.data["dsInfo"]["dsid"],
            }
        )
        req = self.session.get(self._calendar_refresh_url, params=params)
        self.response = req.json()

    def events(self, from_dt=None, to_dt=None):
        """
        Retrieves events for a given date range, by default, this month.
        """
        self.refresh_client(from_dt, to_dt)
        return self.response.get("Event")

    def calendars(self):
        """
        Retrieves calendars of this month.
        """
        today = datetime.today()
        first_day, last_day = monthrange(today.year, today.month)
        from_dt = datetime(today.year, today.month, first_day)
        to_dt = datetime(today.year, today.month, last_day)
        params = dict(self.params)
        params.update(
            {
                "lang": "en-us",
                "usertz": get_localzone().zone,
                "startDate": from_dt.strftime("%Y-%m-%d"),
                "endDate": to_dt.strftime("%Y-%m-%d"),
                "dsid": self.session.service.data["dsInfo"]["dsid"],
            }
        )
        req = self.session.get(self._calendars, params=params)
        self.response = req.json()
        return self.response["Collection"]
