"""Fill in a module description here"""

# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/01_core.ipynb.

# %% auto 0
__all__ = ['stripe_api_url', 'StripeApi']

# %% ../nbs/01_core.ipynb 2
from collections import defaultdict
from fastcore.all import *
from .endpoints import eps
from inspect import Parameter, Signature

import httpx, re

# %% ../nbs/01_core.ipynb 4
stripe_api_url = 'https://api.stripe.com'

# %% ../nbs/01_core.ipynb 7
def _flatten_data(data, prefix=''):
    'Flatten a dictionary of data so that it can be used in a request body.'
    result = {}
    for k,v in data.items():
        key = f'{prefix}[{k}]' if prefix else k
        if isinstance(v, dict): result.update(_flatten_data(v, key))
        elif isinstance(v, list): 
            for i,item in enumerate(v):
                if isinstance(item, dict): result.update(_flatten_data(item, f'{key}[{i}]'))
                else: result[f'{key}[{i}]'] = item
        else: result[key] = v
    return result

# %% ../nbs/01_core.ipynb 13
def _parse_operation_id(op_id):
    'Parse the operation ID to get the resource and verb'
    parts = re.findall(r'[A-Z][a-z]*', op_id)
    verb,*resource_parts = [p.lower() for p in parts]
    r = '_'.join(resource_parts) if resource_parts else 'misc'
    nm = 'create' if verb == 'post' else 'fetch' if verb == 'get' else verb
    return r, nm

# %% ../nbs/01_core.ipynb 17
def _mk_func(path, verb, param_info, summary, hdrs={}):
    'Create a function from the Stripe API endpoint'
    sig_params = [Parameter(param['name'], Parameter.KEYWORD_ONLY, default=None) for param in param_info]
    param_docs = '\n'.join(f"    {param['name']}: {param['description']}" for param in param_info)
    docstring = f"{summary}\n\nParameters:\n{param_docs}" if param_docs else summary
    def m(**kwargs): return dict2obj(getattr(httpx, verb)(stripe_api_url + path, headers=hdrs,
                                                          params=_flatten_data(kwargs)).json())
    m.__signature__ = Signature(sig_params)
    m.__doc__ = docstring
    return m

# %% ../nbs/01_core.ipynb 18
class StripeApi:
    def __init__(self, api_key=None, base_url=stripe_api_url):
        self.api_key,self.base_url = api_key,base_url
        self.hdrs = {'Authorization': f'Bearer {self.api_key}'}
        groups = defaultdict(list)
        for ep in eps:
            r, nm = _parse_operation_id(ep['op_id'])
            groups[r].append((ep['path'], ep['verb'], nm, ep['summary'], ep['params']))
        for r, mtds in groups.items():
            group = AttrDict()
            for path, verb, method_name, summary, params in mtds:
                setattr(group, method_name, _mk_func(path, verb, params, summary, hdrs=self.hdrs))
            setattr(self, r, group)

# %% ../nbs/01_core.ipynb 28
@patch
def find_product(self:StripeApi, name: str):
    'Find a product by name'
    prods = L(self.products.fetch().data)
    return first(prods, lambda p: p.name == name)

# %% ../nbs/01_core.ipynb 30
@patch
def find_prices(self:StripeApi, product_id: str):
    'Find all prices associated with a product id'
    return L(self.prices.fetch().data).filter(lambda p: p.product == product_id)

# %% ../nbs/01_core.ipynb 32
@patch
def priced_product(self:StripeApi, product_name, amount_cents, currency='usd', recurring=None, description=None):
    "Create a product and price if they don't exist"
    prod_params = dict(name=product_name)
    if description: prod_params['description'] = description
    prod = self.find_product(product_name) or self.products.create(**prod_params)
    price_params = dict(product=prod.id, unit_amount=amount_cents, currency=currency)
    if recurring: price_params['recurring'] = recurring
    price = first(self.find_prices(prod.id)) or self.prices.create(**price_params)
    return prod, price

# %% ../nbs/01_core.ipynb 35
@patch
def one_time_payment(self:StripeApi, product_name, amount_cents, success_url, cancel_url, currency='usd', **kw):
    'Create a simple one-time payment checkout'
    _, price = self.priced_product(product_name, amount_cents, currency)
    return self.checkout_sessions.create(mode='payment', line_items=[dict(price=price.id, quantity=1)],
                                         automatic_tax={'enabled': True}, success_url=success_url, cancel_url=cancel_url, **kw)

# %% ../nbs/01_core.ipynb 38
@patch
def subscription(self:StripeApi, product_name, amount_cents, success_url, cancel_url,
                 currency='usd', interval='month', **kw):
    'Create a simple recurring subscription'
    _, price = self.priced_product(product_name, amount_cents, currency, recurring=dict(interval=interval))
    return self.checkout_sessions.create(mode='subscription', success_url=success_url, cancel_url=cancel_url,
                                         line_items=[dict(price=price.id, quantity=1)], **kw)
