# Extensions to the Plenty Rest API and tools specific to gomazing
import csv
import datetime
import json
import time
import urllib

from pathlib import Path

from ..config import *


class ElasticExport(list):
    """Used to fetch CSVs from plenty provided by elastic export"""

    @classmethod
    def fetch(cls, exportno, cacheseconds=600):
        url = ELASTICEXPORTURLS[exportno]    
        cachefile = CACHEPATH / Path(f"elasticexport{exportno}.csv")
        if (cachefile.exists() and time.time() - cachefile.stat().st_mtime <
                cacheseconds):
            f = open(cachefile, newline='')
            data = f.readlines()
        else:
            f = urllib.request.urlopen(url)
            data = f.read().decode('utf-8').split('\n')
            with open(cachefile, 'w') as cf:
                cf.write('\n'.join(data))
        f.close()
        return cls(csv.DictReader(data, delimiter=';'))


class GMZCheapestPriceHistory:
    """Use gomazing sales price and property 298 to collect and calculate
    the cheapest price for the last 30 days"""

    def __init__(self, pricehistorystr='{}', islegacy=False):
        """pricehistorystr: dates and prices as a string representing a
                            json array like this {'YYYYMMDD': 9.99, .. }
        """

        self.pricehistory = json.loads(pricehistorystr)
        # still uses the old property 295 instead of 298
        self.islegacy = islegacy

    @staticmethod
    def nowstr():
        now = datetime.datetime.now()
        return now.strftime('%Y%m%d')

    @staticmethod
    def oldstr(days):
        now = datetime.datetime.now() - datetime.timedelta(days=days)
        return now.strftime('%Y%m%d')

    def add_price(self, price):
        # only change if new price is lower
        nowstr = self.nowstr()
        old = self.pricehistory.get(nowstr, None)
        if old is None or price < old:
            self.pricehistory[nowstr] = price
        # we only track price increases if we lower throw away the old ones
        for datestr in list(self.pricehistory):
            if self.pricehistory[datestr] > price:
                del self.pricehistory[datestr]

    def remove_old_prices(self, days=30):
        # isoformat sorts naturally so we can just work with strings
        oldstr = self.oldstr(days)
        for datestr in list(self.pricehistory):
            if datestr < oldstr:
                del self.pricehistory[datestr]

    def get_cheapest(self):
        return min(self.pricehistory.values())

    def save_to_plenty(self, plenty, variationid):
        self.remove_old_prices()
        hstr = json.dumps(self.pricehistory)
        plenty.put_pim_variation_text_property(variationid, 298, 41, hstr)
        if self.islegacy:
            r = plenty.delete_pim_variation_property(variationid, 295, 41)

    @classmethod
    def get_from_variation(cls, variation):
        """variation is a PlentyVariation object"""

        prop = variation.get_property(298)
        if prop:
            return cls(prop.value)
        prop = variation.get_property(295)
        if prop:
            return cls(prop.value, True)
        return cls()
