from ..utils import rest
from starkcore.utils.resource import Resource
from starkcore.utils.checks import check_datetime


class IssuingCard(Resource):

    """# IssuingCard object
    The IssuingCard object displays the informations of Cards created in your Workspace.
    ## Parameters (required):
    - holder_name [string]: card holder name. ex: "Tony Stark"
    - holder_tax_id [string]: card holder tax ID. ex: "012.345.678-90"
    - holder_external_id [string] card holder unique id, generated by the user to avoid duplicated holders. ex: "my-entity/123"
    ## Parameters (optional):
    - display_name [string, default None]: card displayed name. ex: "ANTHONY STARK"
    - rules [list of IssuingRule, default None]: [EXPANDABLE] list of card spending rules.
    - bin_id [string, default None]: BIN ID to which the card is bound. ex: "53810200"
    - tags [list of strings]: list of strings for tagging. ex: ["travel", "food"]
    - street_line_1 [string, default None]: card holder main address. ex: "Av. Paulista, 200"
    - street_line_2 [string, default None]: card holder address complement. ex: "Apto. 123"
    - district [string]: card holder address district / neighbourhood. ex: "Bela Vista"
    - city [string, default None]: card holder address city. ex: "Rio de Janeiro"
    - state_code [string, default None]: card holder address state. ex: "GO"
    - zip_code [string]: card holder address zip code. ex: "01311-200"
    ## Attributes (return-only):
    - id [string]: unique id returned when IssuingCard is created. ex: "5656565656565656"
    - holder_id [string]: card holder unique id. ex: "5656565656565656"
    - type [string]: card type. ex: "virtual"
    - status [string]: current IssuingCard status. ex: "canceled" or "active"
    - number [string]: [EXPANDABLE] masked card number. Expand to unmask the value. ex: "123".
    - security_code [string]: [EXPANDABLE] masked card verification value (cvv). Expand to unmask the value. ex: "123".
    - expiration [string]: [EXPANDABLE] masked card expiration datetime. Expand to unmask the value. ex: datetime.datetime(2020, 3, 10, 10, 30, 0, 0).
    - updated [datetime.datetime]: latest update datetime for the IssuingCard. ex: datetime.datetime(2020, 3, 10, 10, 30, 0, 0)
    - created [datetime.datetime]: creation datetime for the IssuingCard. ex: datetime.datetime(2020, 3, 10, 10, 30, 0, 0)
    """

    def __init__(self, holder_name, holder_tax_id, holder_external_id, id=None, holder_id=None, type=None, display_name=None, status=None,
                 rules=None, bin_id=None, street_line_1=None, street_line_2=None, district=None, city=None, state_code=None, zip_code=None,
                 tags=None, created=None, updated=None, number=None, security_code=None, expiration=None):
        Resource.__init__(self, id=id)
        self.id = id
        self.holder_id = holder_id
        self.holder_name = holder_name
        self.holder_tax_id = holder_tax_id
        self.holder_external_id = holder_external_id
        self.type = type
        self.display_name = display_name
        self.status = status
        self.rules = rules
        self.bin_id = bin_id
        self.street_line_1 = street_line_1
        self.street_line_2 = street_line_2
        self.district = district
        self.city = city
        self.state_code = state_code
        self.zip_code = zip_code
        self.tags = tags
        self.created = check_datetime(created)
        self.updated = check_datetime(updated)
        self.number = number
        self.security_code = security_code
        self.expiration = expiration


_resource = {"class": IssuingCard, "name": "IssuingCard"}


def create(cards, expand=None, user=None):
    """# Create IssuingCards
    Send a list of IssuingCard objects for creation in the Stark Infra API
    ## Parameters (required):
    - cards [list of IssuingCard objects]: list of IssuingCard objects to be created in the API
    ## Parameters (optional):
    - expand [list of strings, default []]: fields to expand information. ex: ["rules", "security_code", "number", "expiration"]
    - user [Organization/Project object, default None]: Organization or Project object. Not necessary if starkinfra.user was set before function call
    ## Return:
    - list of IssuingCard objects with updated attributes
    """
    return rest.post_multi(resource=_resource, entities=cards, expand=expand, user=user)


def query(status=None, types=None, holder_ids=None, after=None, before=None, tags=None, ids=None, limit=None, expand=None, user=None):
    """# Retrieve IssuingCards
    Receive a generator of IssuingCards objects previously created in the Stark Infra API
    ## Parameters (optional):
    - status [string, default None]: filter for status of retrieved objects. ex: "paid" or "registered"
    - types [list of strings, default None]: card type. ex: ["virtual"]
    - holder_ids [list of strings]: card holder IDs. ex: ["5656565656565656", "4545454545454545"]
    - after [datetime.date or string, default None] date filter for objects created only after specified date. ex: datetime.date(2020, 3, 10)
    - before [datetime.date or string, default None] date filter for objects created only before specified date. ex: datetime.date(2020, 3, 10)
    - tags [list of strings, default None]: tags to filter retrieved objects. ex: ["tony", "stark"]
    - ids [list of strings, default None]: list of ids to filter retrieved objects. ex: ["5656565656565656", "4545454545454545"]
    - limit [integer, default None]: maximum number of objects to be retrieved. Unlimited if None. ex: 35
    - expand [list of strings, default []]: fields to expand information. ex: ["rules", "security_code", "number", "expiration"]
    - user [Organization/Project object, default None]: Organization or Project object. Not necessary if starkinfra.user was set before function call
    ## Return:
    - generator of IssuingCards objects with updated attributes
    """
    return rest.get_stream(
        resource=_resource,
        status=status,
        types=types,
        holder_ids=holder_ids,
        after=check_datetime(after),
        before=check_datetime(before),
        tags=tags,
        ids=ids,
        limit=limit,
        expand=expand,
        user=user,
    )


def page(status=None, types=None, holder_ids=None, after=None, before=None, tags=None, ids=None,
         limit=None, cursor=None, expand=None, user=None):
    """# Retrieve paged IssuingCards
    Receive a list of IssuingCards objects previously created in the Stark Infra API and the cursor to the next page.
    ## Parameters (optional):
    - status [string, default None]: filter for status of retrieved objects. ex: "paid" or "registered"
    - types [list of strings, default None]: card type. ex: ["virtual"]
    - holder_ids [list of strings, default None]: card holder IDs. ex: ["5656565656565656", "4545454545454545"]
    - after [datetime.date or string, default None] date filter for objects created only after specified date. ex: datetime.date(2020, 3, 10)
    - before [datetime.date or string, default None] date filter for objects created only before specified date. ex: datetime.date(2020, 3, 10)
    - tags [list of strings, default None]: tags to filter retrieved objects. ex: ["tony", "stark"]
    - ids [list of strings, default None]: list of ids to filter retrieved objects. ex: ["5656565656565656", "4545454545454545"]
    - limit [integer, default None]: maximum number of objects to be retrieved. Unlimited if None. ex: 35
    - cursor [string, default None]: cursor returned on the previous page function call
    - expand [list of strings, default []]: fields to expand information. ex: ["rules", "security_code", "number", "expiration"]
    - user [Organization/Project object, default None]: Organization or Project object. Not necessary if starkinfra.user was set before function call
    ## Return:
    - list of IssuingCards objects with updated attributes
    - cursor to retrieve the next page of IssuingCards objects
    """
    return rest.get_page(
        resource=_resource,
        status=status,
        types=types,
        holder_ids=holder_ids,
        after=check_datetime(after),
        before=check_datetime(before),
        tags=tags,
        ids=ids,
        limit=limit,
        cursor=cursor,
        expand=expand,
        user=user,
    )


def get(id, expand=None, user=None):
    """# Retrieve a specific IssuingCards
    Receive a single IssuingCards object previously created in the Stark Infra API by its id
    ## Parameters (required):
    - id [string]: object unique id. ex: "5656565656565656"
    ## Parameters (optional):
    - user [Organization/Project object, default None]: Organization or Project object. Not necessary if starkinfra.user was set before function call
    ## Return:
    - IssuingCards object with updated attributes
    """
    return rest.get_id(resource=_resource, id=id, expand=expand, user=user)


def update(id, status=None, display_name=None, rules=None, tags=None, user=None):
    """# Update IssuingCard entity
    Update an IssuingCard by passing id.
    ## Parameters (required):
    - id [string]: IssuingCard id. ex: '5656565656565656'
    ## Parameters (optional):
    - status [string]: You may block the IssuingCard by passing 'blocked' in the status
    - display_name [string, default None]: card displayed name
    - rules [list of dictionaries, default None]: list of dictionaries with "amount": int, "currencyCode": string, "id": string, "interval": string, "name": string pairs.
    - tags [list of strings]: list of strings for tagging
    - user [Organization/Project object, default None]: Organization or Project object. Not necessary if starkinfra.user was set before function call
    ## Return:
    - target IssuingCard with updated attributes
    """
    payload = {
        "status": status,
        "display_name": display_name,
        "rules": rules,
        "tags": tags,
    }
    return rest.patch_id(resource=_resource, id=id, user=user, payload=payload)


def delete(id, user=None):
    """# Delete an IssuingCard entity
    Delete an IssuingCard entity previously created in the Stark Infra API
    ## Parameters (required):
    - id [string]: IssuingCard unique id. ex: "5656565656565656"
    ## Parameters (optional):
    - user [Organization/Project object, default None]: Organization or Project object. Not necessary if starkinfra.user was set before function call
    ## Return:
    - deleted IssuingCard object
    """
    return rest.delete_id(resource=_resource, id=id, user=user)
