"""Small server-side client. pip install httpx. Keep keys outside client apps."""
from urllib.parse import quote,urlencode
import httpx


class BotDock:
    def __init__(self, base_url, project_id, token):
        self.base = base_url.rstrip('/') + '/api/v1/projects/' + quote(project_id, safe='')
        self.client = httpx.Client(headers={'Authorization': 'Bearer ' + token}, timeout=30, follow_redirects=False)

    def close(self):
        self.client.close()

    def request(self, method, path, body=None, key=None):
        response = self.client.request(method, self.base + path, json=body, headers={'Idempotency-Key': key} if key else {})
        response.raise_for_status()
        return response.json()

    def profiles(self):
        return self.request('GET', '/profiles')

    def profile(self, profile_id):
        return self.request('GET', '/profiles/' + quote(profile_id, safe=''))

    def update_profile(self, profile_id, **changes):
        return self.request('PATCH', '/profiles/' + quote(profile_id, safe=''), changes)

    def send(self, identity_id, text, *, idempotency_key):
        return self.request('POST', '/messages', {'identity_id': identity_id, 'text': text}, idempotency_key)

    def event(self, identity_id, text, data, *, event_id):
        return self.request('POST', '/events', {'identity_id': identity_id, 'text': text, 'data': data, 'event_id': event_id})

    def run(self, operation_id, inputs, *, idempotency_key, identity_id=None, environment='sandbox'):
        return self.request('POST', '/operations/' + quote(operation_id, safe='') + '/runs', {'input': inputs, 'identity_id': identity_id, 'environment': environment}, idempotency_key)

    def job(self, job_id):
        return self.request('GET', '/jobs/' + quote(job_id, safe=''))

    def start_workflow(self, workflow_id, inputs, *, idempotency_key, identity_id=None):
        return self.request('POST', '/workflows/' + quote(workflow_id, safe='') + '/run',
                            {'input': inputs, 'identity_id': identity_id}, idempotency_key)

    def workflow_run(self, run_id):
        return self.request('GET', '/workflow-runs/' + quote(run_id, safe=''))

    def automation_event(self, source, data, *, event_id, environment='sandbox', identity_id=None):
        return self.request('POST', '/automation-events', {'source': source, 'data': data,
                            'event_id': event_id, 'environment': environment, 'identity_id': identity_id})

    def audit(self, after=0):
        return self.request('GET', '/audit?after=' + str(int(after)))

    def refund(self, order_id, *, idempotency_key, receipt=None):
        return self.request('POST', '/payments/' + quote(order_id, safe='') + '/refund', {'receipt': receipt}, idempotency_key)

    def tables(self):
        return self.request('GET','/tables')

    def rows(self, table_id, *, environment='live', offset=0, limit=100):
        return self.request('GET','/tables/'+quote(table_id,safe='')+'/rows?'+urlencode({'environment':environment,'offset':offset,'limit':limit}))

    def append_rows(self, table_id, rows, *, idempotency_key, environment='sandbox'):
        return self.request('POST','/tables/'+quote(table_id,safe='')+'/rows',{'rows':rows,'environment':environment},idempotency_key)

    def analytics(self, *, environment='live', days=30, channel_id=''):
        return self.request('GET','/analytics?'+urlencode({'environment':environment,'days':days,'channel_id':channel_id}))
