from requests import get
from bs4 import BeautifulSoup
import csv
from os import path
from os import getcwd
from tempfile import NamedTemporaryFile
import shutil


def getData(regular_price, headers, url):
    url = url.strip()
    discount = 0
    price = ''
    category = '-'
    name = ''
    error_msg = "An item can't be found. Check the csv-file! \n"
    jimms = 'https://www.jimms.'
    multitronic = 'https://www.multitronic.'
    gigantti = 'https://www.gigantti.'

    jimms_dict = {
        "id": "productinfo",
        "itemprop": "name",
        "itemprop1": "price",
        "class1": "filteritem selectitem activechild",
        "class2": "treefilter-item"
    }
    multitronic_dict = {
        "id": "product_wrapper",
        "class": "hide640",
        "id1": "vat",
        "class1": "level1 active",
        "class2": "active"
    }

    # get a Response object of the website to use BS4 on
    page = get(url, headers=headers)
    soup = BeautifulSoup(page.content, 'html.parser')

    # getAttrs()
    if url[:len(jimms)] == jimms:
        name, price, category = getAttrs(soup, jimms_dict)
        if category != "not found":
            price = int(price.get_text()[:-3])
            category = category.get_text()
        else:
            print(error_msg)

    elif url[:len(multitronic)] == multitronic:
        name, price, category = getAttrs(soup, multitronic_dict)
        if category != "not found":
            price = int(price.get_text()[:-5])
            category = category.find('a', class_="nLink").get_text()
        else:
            print(error_msg)

    elif url[:len(gigantti)] == gigantti:
        container = soup.find(attrs={"class": "product-detail-page"})
        if container is not None:
            name_help = container.find("meta", itemprop="name")
            name = name_help["content"]
            price_help = container.find("meta", itemprop="price")
            price = int(price_help["content"])
        else:
            print(error_msg)

    if (regular_price - price) > 0:
        discount = regular_price - price

    return name, price, discount, category


def getAttrs(soup, contents):
    keys = list(contents.keys())
    base_container = soup.find(attrs={keys[0]: contents[keys[0]]})
    if base_container:
        name = base_container.find(attrs={keys[1]: contents[keys[1]]}).get_text()
        price = base_container.find(attrs={keys[2][:-1]: contents[keys[2]]})
        active_container = soup.find(attrs={keys[3][:-1]: contents[keys[3]]})
        category = active_container.find(attrs={keys[4][:-1]: contents[keys[4]]})
    else:
        name = "not found"
        price = 0
        category = "not found"
    return name, price, category


def execTracker():
    headers = {"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                             'AppleWebKit/537.36 (KHTML, like Gecko) '
                             'Chrome/81.0.4044.122 Safari/537.36'}
    urls = open("urls.csv", "r")
    items = {'title': 'price'}
    discounts = {'title': 'discount'}
    categories = {'title': 'category'}
    names = ['title']
    lowest_of_categories = {'types': 'price'}
    url_dict = {'title': 'url'}
    lowest_price_seen = {'title': 'lowest price seen'}
    total = 'Lowest total'
    sum_of_prices = 0
    discount_sum = 0
    new_lowest_prices = []
    new_regular_prices = []

    for row in urls:
        url, regular_price, lowest_of_url = row.split(',')
        regular_price = int(regular_price.strip())
        lowest_of_url = int(lowest_of_url.strip())

        # getData()
        name, price, discount, category = getData(regular_price, headers, row)
        
        items[name] = price
        discounts[name] = discount
        discount_sum += discount
        categories[name] = category
        url_dict[name] = url.strip()
        names.append(name)

        # check if price is lowest of that category
        if category not in lowest_of_categories:
            if category != '-':
                sum_of_prices += price
            lowest_of_categories[category] = price
        else:
            if price < lowest_of_categories[category] and category != '-':
                sum_of_prices -= lowest_of_categories[category]
                sum_of_prices += price
                lowest_of_categories[category] = price

        # check if price is lowest ever on the webpage
        if price < lowest_of_url:
            new_lowest_prices.append(price)
            lowest_price_seen[name] = price
        else:
            new_lowest_prices.append(lowest_of_url)
            lowest_price_seen[name] = lowest_of_url

        # print message and update price if higher
        if discount != 0 and name != "not found":
            print(name + ' ({0}€) has a discount of {1}€! The lowest price seen is {2}€. \n'.format(price, discount, lowest_of_url))
            new_regular_prices.append(regular_price)
        elif (regular_price - price) < 0:
            print('The price of ' + name + ' is higher than before! :( '
                        'old: ' + str(regular_price) + ' new: ' + str(price) + '\n')
            new_regular_prices.append(price)
        else:
            new_regular_prices.append(regular_price)

    urls.close()

    if discount_sum == 0:
        print('No discounts this time...')

    names.append(total)
    items[total] = sum_of_prices
    discounts[total] = discount_sum
    categories[total] = ' '
    lowest_price_seen[total] = sum_of_prices
    url_dict[total] = ' '

    makeCsv(items, names, discounts, categories, url_dict, lowest_price_seen, 'result.csv')
    updateSourceCsv(new_lowest_prices, new_regular_prices)

    return


def updateSourceCsv(new_lowest_prices, new_regular_prices):
    tempfile = NamedTemporaryFile(mode='w', delete=False, newline='')
    with open("urls.csv", 'r') as csvFile, tempfile:
        reader = csv.reader(csvFile, delimiter=',', quotechar='"')
        writer = csv.writer(tempfile, delimiter=',', quotechar='"')
        i = 0
        for row in reader:
            row[1] = new_regular_prices[i] 
            row[2] = new_lowest_prices[i]
            i += 1
            writer.writerow(row)

    shutil.move(tempfile.name, "urls.csv")


def makeCsv(items, fieldnames, discounts, categories, urls, lowest_prices, file_name):
    file_path = path.join(getcwd(), file_name)

    csv_file = open(file=file_path, mode="w+", encoding="utf-8", newline='')
    writer = csv.DictWriter(csv_file, fieldnames=fieldnames)

    writer.writeheader()
    writer.writerow(categories)
    writer.writerow(items)
    writer.writerow(discounts)
    writer.writerow(urls)
    writer.writerow(lowest_prices)

    csv_file.close()


def main():
    execTracker()
    print('Success! Results can be found in result.csv in the project folder :) \n')


main()
