import parse
from decimal import Decimal
import delorean


class SaleLog(object):

    def __init__(self, timestamp, product_id, price, name, discount,
                 shop=None):
        self.timestamp = timestamp
        self.product_id = product_id
        self.price = price
        self.name = name
        self.discount = discount
        self.shop = shop

    def __repr__(self):
        return '<SaleLog ({}, {}, {})>'.format(self.timestamp,
                                               self.product_id,
                                               self.price)

    @classmethod
    def row_header(cls):
        HEADER = ('Czas', 'Sklep', 'Nr produktu', 'Nazwa', 'Cena',
                  'Rabat')
        return HEADER

    def row(self):
        return (self.timestamp.datetime.isoformat(), self.shop,
                self.product_id, self.name, self.price,
                '{}%'.format(self.discount))

    @classmethod
    def from_row(cls, row):
        timestamp_str, shop, product_id, name, raw_price, discount_str = row
        timestamp = delorean.parse(timestamp_str)
        discount = parse.parse('{:d}%', discount_str)[0]
        # Zaokrąglanie, aby uniknąć możliwych błędów zaokrąglania w Excelu.
        price = round(Decimal(raw_price), 2)

        return cls(timestamp=timestamp, product_id=product_id,
                   price=price, name=name, discount=discount,
                   shop=shop)

    @classmethod
    def parse(cls, shop, text_log):
        '''
        Przetwarzanie wpisów z dziennika w formacie
        [<czas>] - SPRZEDAŻ - PRODUKT: <nr produktu> - CENA: $<cena> - NAZWA: <nazwa> - RABAT: <rabat>%
        na obiekt SaleLog.
        '''
        def price(string):
            return Decimal(string)

        def isodate(string):
            return delorean.parse(string)

        FORMAT = ('[{timestamp:isodate}] - SPRZEDAŻ - PRODUKT: {product:d} '
                  '- CENA: ${price:price} - NAZWA: {name:D} '
                  '- RABAT: {discount:d}%')

        formats = {'price': price, 'isodate': isodate}
        result = parse.parse(FORMAT, text_log, formats)

        return cls(timestamp=result['timestamp'],
                   product_id=result['product'],
                   price=result['price'],
                   name=result['name'],
                   discount=result['discount'],
                   shop=shop)
