from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from config.config import (
    ChromeOptionsBuilder,
    get_chrome_web_driver,
)
from selenium.common.exceptions import NoSuchElementException

class AmazonAPI:
    def __init__(self, base_url, currency, product_links):
        self.base_url = base_url
        self.product_links = product_links
        options = ChromeOptionsBuilder().headless().ignore_certificate_error().browser_as_incognito().loglevel(2).build()
        self.driver = get_chrome_web_driver(options)
        self.currency = currency

    def run(self):
        print("Starting Script...")
        links = self.product_links
        if not links:
            print("Stopped script.")
            return
        print(f"Got {len(links)} links to products...")
        print("Getting info about products...")
        products = self.get_products_info(links)
        print(f"Got info about {len(products)} products...")
        self.driver.quit()
        return products

    def get_products_info(self, links):
        asins = self.get_asins(links)
        products = []
        for asin in asins:
            product = self.get_single_product_info(asin)
            if product:
                products.append(product)
        return products

    def get_asins(self, links):
        return [self.get_asin(link) for link in links]

    def get_single_product_info(self, asin):
        print(f"Product ID: {asin} - getting data...")
        product_short_url = self.shorten_url(asin)
        self.driver.get(f'{product_short_url}?language=en_GB')
        price = self.get_price()
        title = self.get_title()
        seller = self.get_seller()
        merchant = self.get_merchant()

        if title and seller and price:
            product_info = {
                'asin': asin,
                'url': product_short_url,
                'title': title,
                'seller': seller,
                'price': price,
                'merchant': merchant
            }
            return product_info
        return None

    def get_title(self):
        try:
            return self.driver.find_element_by_id('productTitle').text
        except Exception as e:
            print(e)
            print(f"Can't get title of a product - {self.driver.current_url}")
            return None

    def get_seller(self):
        try:
            return self.driver.find_element_by_id('bylineInfo').text
        except Exception as e:
            print(e)
            print(f"Can't get seller of a product - {self.driver.current_url}")
            return None
    def get_merchant(self):
        try:
            return self.driver.find_element_by_id('sellerProfileTriggerId').text
        except Exception as e:
            print(e)
            print(f"Can't get seller of a product - {self.driver.current_url}")
            return None
    def get_price(self):
        price = None
        try:
            element_present = EC.presence_of_element_located((By.ID, 'priceblock_ourprice'))
            WebDriverWait(self.driver, 10).until(element_present)
            price = self.driver.find_element_by_id('priceblock_ourprice').text
            price = self.convert_price(price)
        except TimeoutException:
                print("Timed out waiting for page to load, ourprice")
                print("Checking dealprice")
                try:
                    element_present = EC.presence_of_element_located((By.ID, 'priceblock_dealprice'))
                    WebDriverWait(self.driver, 5).until(element_present)
                    price = self.driver.find_element_by_id('priceblock_dealprice').text
                    price = self.convert_price(price)
                except TimeoutException:
                        print("Timed out waiting for page to load")
        except NoSuchElementException:
            try:
                availability = self.driver.find_element_by_id('availability').text
                if 'Available' in availability:
                    price = self.driver.find_element_by_class_name('olp-padding-right').text
                    price = price[price.find(self.currency):]
                    price = self.convert_price(price)
            except Exception as e:
                print(e)
                print(f"Can't get price of a product - {self.driver.current_url}")
                return None
        except Exception as e:
            print(e)
            print(f"Can't get price of a product - {self.driver.current_url}")
            return None
        return price

    @staticmethod
    def get_asin(product_link):
        return product_link[product_link.find('/dp/') + 4:product_link.find('/ref')]

    def shorten_url(self, asin):
        return self.base_url + 'dp/' + asin

    def convert_price(self, price):
        price = price.split(self.currency)[1]
        try:
            price = price.split("\n")[0] + "." + price.split("\n")[1]
        except:
            Exception()
        try:
            price = price.split(",")[0] + price.split(",")[1]
        except:
            Exception()
        return float(price)