from datetime import datetime

from fortnite_api.cosmetics import BrCosmetic


class BrShop:
    """Represents a Battle Royale shop.

    Attributes
    -----------
    hash: :class:`str`
        The hash of the shop.
    date: :class:`datetime.datetime`
        The timestamp of the .
    featured: Optional[List[:class:`BrShopEntry`]]
        A list of all featured entries.
    daily: Optional[List[:class:`BrShopEntry`]]
        A list of all daily entries.
    votes: Optional[List[:class:`BrShopEntry`]]
        A list of all vote entries.
    vote_winners: Optional[List[:class:`BrShopEntry`]]
        A list of all vote winner.
    raw_data: :class:`dict`
        The raw data from request. Can be used for saving and re-creating the class.
    """

    def __init__(self, data):
        self.hash = data.get('hash')
        try:
            self.date = datetime.strptime(data.get('date'), '%Y-%m-%dT%H:%M:%S%z')
        except (ValueError, ValueError):
            self.date = None
        self.featured = BrShopSection(data.get('featured')) if data.get('featured') else None
        self.daily = BrShopSection(data.get('daily')) if data.get('daily') else None
        self.special_featured = BrShopSection(data.get('specialFeatured')) if data.get('specialFeatured') else None
        self.special_daily = BrShopSection(data.get('specialDaily')) if data.get('specialDaily') else None
        self.votes = BrShopSection(data.get('votes')) if data.get('votes') else None
        self.vote_winners = BrShopSection(data.get('voteWinners')) if data.get('voteWinners') else None
        self.raw_data = data


class BrShopSection:

    def __init__(self, data):
        self.name = data.get('name')
        self.entries = [BrShopEntry(entry_data) for entry_data in data.get('entries')] if data.get('entries') else None
        self.raw_data = data


class BrShopEntry:
    """Represents a Battle Royale shop entry.

    Attributes
    -----------
    regular_price: :class:`int`
        The internal price.
    final_price: :class:`int`
        The price which is shown in-game.
    discount: :class:`int`
        The discount on the item.
    giftable: :class:`bool`
        Whether the item is giftable.
    refundable: :class:`bool`
        Whether the item is refundable.
    panel: :class:`int`
        The id of the panel in the featured section. -1 if the item is in no panel.
    sort_priority: :class:`int`
        The sort priority in the featured panels.
    banner: Optional[:class:`str`]
        The text of the banner. This text is shown in a arrow in-game.
    items: List[:class:`BrCosmetic`]
        A list of all cosmetics you get when you buy.
    raw_data: :class:`dict`
        The raw data from request. Can be used for saving and re-creating the class.
    """

    def __init__(self, data):
        self.regular_price = data.get('regularPrice')
        self.final_price = data.get('finalPrice')
        self.discount = self.regular_price - self.final_price if self.regular_price and self.final_price else None
        self.bundle = BrShopBundle(data.get('bundle')) if data.get('bundle') else None
        self.banner = BrShopBanner(data.get('banner')) if data.get('banner') else None
        self.giftable = data.get('giftable')
        self.refundable = data.get('refundable')
        self.sort_priority = data.get('sortPriority')
        self.categories = data.get('categories')
        self.dev_name = data.get('devName')
        self.offer_id = data.get('offerId')
        self.display_asset_path = data.get('displayAssetPath')
        self.items = [BrCosmetic(item_data) for item_data in data.get('items')]
        self.raw_data = data


class BrShopBundle:

    def __init__(self, data):
        self.name = data.get('name')
        self.image = data.get('image')
        self.raw_data = data


class BrShopBanner:

    def __init__(self, data):
        self.value = data.get('value')
        self.backend_value = data.get('backendValue')
        self.raw_data = data
