import json
import sys

from datetime import date, datetime, timedelta
from urllib.parse import urljoin

import requests

HOST = 'www.antiochian.org'
CLIENT_ID = 'antiochian_api'
CLIENT_SECRET = 'TAxhx@9tH(l^MgQ9FWE8}T@NWUT9U)'


class Antiochian(requests.Session):
    base_url = 'https://antiochian.org/'
    token_endpoint = urljoin(base_url, '/connect/token')
    liturgical_endpoint = urljoin(base_url, '/api/antiochian/LiturgicalDay/{}')
    id_anchor = None
    days = {}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.headers['Host'] = HOST

    def authenticate(self):
        response = session.post(self.token_endpoint, data={
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'grant_type': 'client_credentials',
        })

        response.raise_for_status()

        token_data = response.json()
        self.headers['Authorization'] = f'Bearer {token_data["access_token"]}'

        # populate self.id_anchor
        self.get_liturgical_day()

    def get_id_from_date(self, dt):
        anchor_dt, anchor_id = self.id_anchor
        span = dt - anchor_dt
        return span.days + anchor_id

    def get_liturgical_day(self, dt=None):
        if dt in self.days:
            # Fetch from cache
            return self.days[dt]

        day_id = self.get_id_from_date(dt) if dt else 0
        url = self.liturgical_endpoint.format(day_id)
        response = self.get(url)

        if not response.ok:
            return None

        response_data = response.json()
        day = response_data['liturgicalDay']

        if not self.id_anchor:
            dt = datetime.strptime(day['originalCalendarDate'], '%Y-%m-%d')
            self.id_anchor = dt.date(), day['itemId']

        # cache
        self.days[dt] = day

        return day


if __name__ == '__main__':
    session = Antiochian()
    session.authenticate()

    for i in range(10):
        dt = date.today() + timedelta(days=i)
        day = session.get_liturgical_day(dt)
        print(
            f'{dt}: {day["feastDayTitle"].title()}\n'
            f'\t{day["fastDesignation"].title()}\n'
        )

        # The api always returns 3 readings, but not all are used
        for num in range(1, 4):
            reading_title = day[f'reading{num}Title']
            if reading_title:
                print(f'\t{reading_title.title()}')

        print()