#
# Copyright (c) Daniel Sheffield 2021
#
# All rights reserved
#
# THIS SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY
from faker import Faker
from psycopg.sql import SQL
from datetime import datetime

class mock_conn(object):
    
    def close(self):
        pass

class mock_cur(object):
    def __init__(self, records):
        self.records = records
    
    def execute(self, *args, **kwargs):
        pass
    
    def fetchall(self):
        yield from (i for i in self.records)
    
    def close(self):
        pass

def cursor_as_dict(cur):
    yield from cur.fetchall()

def get_transactions_statement():
    return ''
    
def get_session_transactions_statement(date, store, full_name=True, exact_time=True):
    return ''

Faker.seed(4321)
fake = Faker()
# first, import a similar Provider or use the default one
from faker.providers import BaseProvider

# create new provider class
class Products(BaseProvider):
    PRODUCTS = {
        'Dark Chocolate': 'Chocolate',
        'Milk Chocolate': 'Chocolate',
        'Cooking Chocolate': 'Chocolate',
        'Cucumber': 'Veggies',
        'Bananas': 'Fruit',
        'Milk': 'Milk and Cream',
        'Cream': 'Milk and Cream',
        'Coffee Beans': 'Coffee',
        'Freerange Eggs': 'Eggs',
    }
    GROUPS = [
        'Fish, Meat, Eggs',
        'Dairy',
        'Beverages',
        'Treats',
        'Produce',
    ]
    CATEGORIES = {
        'Eggs': 'Fish, Meat, Eggs',
        'Milk and Cream': 'Dairy',
        'Chocolate': 'Treats',
        'Veggies': 'Produce',
        'Fruit': 'Produce',
        'Coffee': 'Beverages',
    }
    STORES = [
        'Paknsave',
        'Countdown',
        'New World',
        'Dreamview',
        'TOFS',
    ]
    CATEGORY_UNITS = {
        'Eggs': ('g',),
        'Milk and Cream': ('mL', 'L',),
        'Chocolate': ('g', 'kg',),
        'Veggies': ('g', 'kg', 'Piece',),
        'Fruit': ('g', 'kg', 'Piece', 'Bunch',),
        'Coffee': ('g', 'kg',),
    }
    ORGANIC = [
        True,
        False,
    ]
    def _dict_choice(self, _dict):
        key = fake.random.choice([ i for i in _dict ])
        return key, _dict[key]
    
    def _product_choice(self):
        key = None
        product = []
        for _dict in (
            self.PRODUCTS,
            self.CATEGORIES,
            dict([
                (k, None) for k in self.GROUPS
            ]),
        ):
            if key is None:
                k, key = self._dict_choice(_dict)
                product.append(k)
                continue
            product.append(key)
            key = _dict[key]
        return product
    
    def product(self):
        return self._product_choice()
    
    def product_unit(self, product):
        return fake.random.choice(self.CATEGORY_UNITS[product[1]])
    
    def description(self, *args, **kwargs):
        return fake.sentence(*args, **kwargs)
        
    def store(self):
        return fake.random.choice(self.STORES)
    
    def unit(self):
        return fake.random.choice(self.UNITS)
    
    def organic(self):
        return fake.random.choice(self.ORGANIC)

# then add new provider to faker instance
fake.add_provider(Products)

records = [{
    'ts': datetime(2021, 8, 29, 14, 8, 0, 0),
    'id': 2,
    'code': fake.store()[:4],
    'store': 'Countdown',
    'price': 4.30,
    '$/unit': 4.3/250.0,
    'quantity': 250.0,
    'unit': 'g',
    'organic': False,
    'total': 0,
    'description': 'Whittakers',
    'product': 'Dark Chocolate',
    'group': 'Treats',
    'category': 'Chocolate',
}]
for i in range(0,100):
    product = fake.product()
    quantity = fake.random.random()*500 + 1
    price = fake.random.random()*10
    unit = fake.product_unit(product)
    organic = fake.organic()
    words = []
    words.extend(fake.sentence().split())
    words.append(
        f'{quantity:.2f} {unit} @ {price:.2f}'
    )
    if organic:
        words.append('organic')
    
    records.append({
        'ts': datetime(2021, 8, 29, 14, 8, 0, 0),
        'id': 3,
        'code': fake.store()[:4],
        'store': fake.store(),
        'price': price,
        '$/unit': price/quantity,
        'quantity': quantity,
        'unit': unit,
        'organic': organic,
        'total': 0,
        'description': ' '.join([
            product[0],
            *fake.description(ext_word_list=words).split()
        ]),
        'product': product[0],
        'group': product[2],
        'category': product[1],
    })

conn = mock_conn()
cur = mock_cur(records)
