import pandas as pd
from openpyxl import load_workbook
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
import re
import time
import random
from datetime import datetime

def get_eur_to_gbp_rate():
    """Fetch current EUR to GBP conversion rate"""
    try:
        response = requests.get('https://api.exchangerate-api.com/v4/latest/EUR', timeout=10)
        data = response.json()
        return data['rates']['GBP']
    except Exception as e:
        print(f"Error fetching exchange rate: {e}")
        print("Using fallback rate: 0.85")
        return 0.85

def parse_cardmarket_price(price_text):
    """Convert '141,30 €' format to float in EUR"""
    if not price_text:
        return None
    price_clean = re.sub(r'[^\d,]', '', price_text)
    price_clean = price_clean.replace(',', '.')
    try:
        return float(price_clean)
    except ValueError:
        return None
    
def parse_cardmarket_quantity(quantity_text):
    if not quantity_text:
        return None
    try:
        return float(quantity_text)
    except ValueError:
        return None

def setup_driver():
    """Setup Chrome driver with visible window"""
    chrome_options = Options()
    # Remove headless mode to see the browser
    # chrome_options.add_argument('--headless')
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument('--disable-dev-shm-usage')
    chrome_options.add_argument('--disable-blink-features=AutomationControlled')
    chrome_options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36')
    chrome_options.add_argument('--window-size=1920,1080')
    
    try:
        driver = webdriver.Chrome(options=chrome_options)
        return driver
    except Exception as e:
        print(f"Error setting up Chrome driver: {e}")
        print("Make sure Chrome and chromedriver are installed")
        return None

def scrape_cardmarket_prices_and_quantities_selenium(driver, url):
    try:
        print(f"  Loading page...")
        driver.get(url)
        
        # Wait for page to load + human reading time
        time.sleep(random.uniform(20, 30))
        
        print(f"  Page title: {driver.title}")
        
        offer_container_selector = '#table > div:nth-child(1) > div.table-body > .row.article-row.g-0:nth-child(1) > div.col-offer'
        price_selector = 'div.price-container > div > div:nth-child(1) > span:nth-child(1)'
        quantity_selector = 'div.amount-container > span:nth-child(1)'
        price_quantity_pairs = []
        try:
            offer_containers = driver.find_elements(By.CSS_SELECTOR, offer_container_selector)
            print(f"  Offer container selector: Found {len(offer_containers)} elements")
            for offer_container in offer_containers:
                price_element = offer_container.find_element(By.CSS_SELECTOR, price_selector)
                price_text = price_element.text
                if '€' in price_text and re.search(r'\d', price_text):
                    print(f"  ✓ Found price: {price_text}")
                else:
                    price_text = None

                quantity_element = offer_container.find_element(By.CSS_SELECTOR, quantity_selector)
                quantity_text = quantity_element.text
                
                if price_text is None or quantity_text is None:
                    continue
                price_quantity_pairs.append({
                      'price': parse_cardmarket_price(price_text = price_text)
                    , 'quantity': parse_cardmarket_quantity(quantity_text = quantity_text)
                })
        except Exception as e:
            print(f"  Price selector failed: {e}")
            return []
        
        """
        if price_text is None:
            print(f"  ✗ No price found")
            if quantity_text is not None:
                input("Press Enter to continue to next URL...")
        
        if quantity_text is None:
            print(f"  ✗ No quantity found")
            input("Press Enter to continue to next URL...")
        """
        return price_quantity_pairs # price_text, quantity_text
    
    except Exception as e:
        print(f"  Error: {e}")
        return []

def main():
    workbook_name = 'TCG Sole Trader Copy.xlsx'
    sourcing_sheet_name = 'Sourcing'
    # mtg_set_sheet_name = 'MTG Set'
    product_sheet_name = 'Product'

    print("Loading workbook...")
    wb = load_workbook(workbook_name)
    
    if sourcing_sheet_name not in wb.sheetnames:
        print(f"Error: Sheet '{sourcing_sheet_name}' not found")
        return
    """
    if mtg_set_sheet_name not in wb.sheetnames:
        print(f"Error: Sheet '{mtg_set_sheet_name}' not found")
        return
    """
    if product_sheet_name not in wb.sheetnames:
        print(f"Error: Sheet '{product_sheet_name}' not found")
        return
    
    sourcing_sheet = wb[sourcing_sheet_name]
    # mtg_set_sheet = wb[mtg_set_sheet_name]
    product_sheet = wb[product_sheet_name]

    sourcing_table_found = False
    start_row = None
    for row in range(1, sourcing_sheet.max_row + 1):
        if sourcing_sheet.cell(row, 1).value == 'tbl_Sourcing' or 'Source Name' in str(sourcing_sheet.cell(row, 3).value):
            start_row = row + 1
            sourcing_table_found = True
            break
    
    if not sourcing_table_found or not start_row:
        for row in range(1, min(20, sourcing_sheet.max_row + 1)):
            if 'Source Name' in str(sourcing_sheet.cell(row, 2).value):
                start_row = row + 1
                sourcing_table_found = True
                break
    """
    start_row = None
    # mtg_set_table_found = False
    for row in range(1, mtg_set_sheet.max_row + 1):
        if mtg_set_sheet.cell(row, 1).value == 'tbl_MTG_Set' or 'Set Name' in str(mtg_set_sheet.cell(row, 2).value):
            start_row = row + 1
            mtg_set_table_found = True
            break
    """

    start_row = None
    product_table_found = False
    for row in range(1, product_sheet.max_row + 1):
        if product_sheet.cell(row, 1).value == 'tbl_Product' or 'Product Id' in str(product_sheet.cell(row, 1).value):
            start_row = row + 1
            product_table_found = True
            break

    if not sourcing_table_found:
        print("Error: Could not find table 'tbl_Sourcing' or 'Source Name' column")
        return
    """
    if not mtg_set_table_found:
        print("Error: Could not find table 'tbl_MTG_Set' or 'Set Name' column")
        return
    """
    if not product_table_found:
        print("Error: Could not find table 'tbl_Product' or 'Product Id' column")
        return
    
    header_row = start_row - 1
    source_name_col = None
    source_link_col = None
    source_unit_price_col = None
    source_is_available_col = None
    source_product_id_col = None
    
    product_id_col = None
    product_is_booster_col = None

    for col in range(1, sourcing_sheet.max_column + 1):
        header = str(sourcing_sheet.cell(header_row, col).value).strip()
        if 'Source Name' in header:
            source_name_col = col
        elif 'Source Link' in header:
            source_link_col = col
        elif 'Sale Price' in header:
            source_unit_price_col = col
        elif 'Active' in header:
            source_is_available_col = col
        elif 'Product Id' in header:
            source_product_id_col = col
    
    for col in range(1, product_sheet.max_column + 1):
        header = str(product_sheet.cell(header_row, col).value).strip()
        if 'Is Booster' in header:
            product_is_booster_col = col
        elif 'Product Id' in header:
            product_id_col = col
    
    print(f"Starting from row {start_row}")
    print(f"Sourcing Columns - Source Name: {source_name_col}, Source Link: {source_link_col}, Source Unit Cost: {source_unit_price_col}, Active: {source_is_available_col}, Product Id: {source_product_id_col}")
    print(f"Product Columns - Id: {product_id_col}, Is Booster: {product_is_booster_col}")

    if not all([source_name_col, source_link_col, source_unit_price_col, source_is_available_col, source_product_id_col, product_id_col, product_is_booster_col]):
        print("Error: Could not find required columns")
        return
    
    # Get EUR to GBP rate
    eur_to_gbp = get_eur_to_gbp_rate()
    print(f"Using EUR to GBP rate: {eur_to_gbp}")
    
    # Setup Selenium driver
    print("Setting up browser automation (browser will be visible)...")
    driver = setup_driver()
    if not driver:
        return
    
    try:
        processed_count = 0
        updated_count = 0
        
        for row in range(start_row, sourcing_sheet.max_row + 1):
            source_name = sourcing_sheet.cell(row, source_name_col).value
            source_link = sourcing_sheet.cell(row, source_link_col).value
            source_product_id = sourcing_sheet.cell(row, source_product_id_col).value
            # Check if row is empty
            if not source_name or not source_link or not source_product_id:
                continue

            print(f"found source: {source_name} - product: {source_product_id} - link: {source_link}")

            product_is_booster = False
            for product_row in range(start_row, product_sheet.max_row + 1):
                product_id = product_sheet.cell(product_row, product_id_col).value
                # print(f"found product: id {product_id}")
                if product_id == source_product_id:
                    product_is_booster_text = str(product_sheet.cell(product_row, product_is_booster_col).value).upper()
                    # print(f"product is booster: {product_is_booster_text}, type: {str(type(product_is_booster_text))}")
                    product_is_booster = (product_is_booster_text == "TRUE")
                    break
            print(f"product is booster: {product_is_booster}")
            # Check conditions
            if product_is_booster and source_name == "Card Market" and source_link and str(source_link).strip():
                sourcing_sheet.cell(row, source_unit_price_col).value = None
                # sourcing_sheet.cell(row, source_is_available_col).value = "FALSE"
                
                processed_count += 1
                print(f"\n{'='*60}")
                print(f"Processing row {row}: {source_link}")
                print(f"{'='*60}")
                
                # Scrape price
                price_quantity_pairs = scrape_cardmarket_prices_and_quantities_selenium(driver, source_link)
                
                if price_quantity_pairs:
                    # sourcing_sheet.cell(row, source_is_available_col).value = "TRUE"
                    max_quantity = 0
                    updated_row_price = False
                    for price_quantity_pair in price_quantity_pairs:
                        eur_price = price_quantity_pair['price']
                        quantity = price_quantity_pair['quantity']
                        print(f"  Found price: €{eur_price}")
                        print(f"  Found quantity: {quantity}")
                        max_quantity = max(max_quantity, quantity)
                        if quantity >= 8:
                            if eur_price:
                                gbp_price = eur_price * eur_to_gbp
                                print(f"  Converted: €{eur_price:.2f} → £{gbp_price:.2f}")
                                sourcing_sheet.cell(row, source_unit_price_col).value = gbp_price
                                updated_count += 1
                                updated_row_price = True
                                print(f"output row: {row}, value: {sourcing_sheet.cell(row, source_unit_price_col).value}")
                                break
                            else:
                                print(f"  Error: Could not parse price")
                    if not updated_row_price:
                        print("Offer with quantity >= 8 not found")
                        for price_quantity_pair in price_quantity_pairs:
                            eur_price = price_quantity_pair['price']
                            quantity = price_quantity_pair['quantity']
                            print(f"  Found price: €{eur_price}")
                            print(f"  Found quantity: {quantity}")
                            if max_quantity <= 2 or quantity == max_quantity:
                                if eur_price:
                                    gbp_price = eur_price * eur_to_gbp
                                    print(f"  Converted: €{eur_price:.2f} → £{gbp_price:.2f}")
                                    sourcing_sheet.cell(row, source_unit_price_col).value = gbp_price
                                    updated_count += 1
                                    updated_row_price = True
                                    print(f"output row: {row}, value: {sourcing_sheet.cell(row, source_unit_price_col).value}")
                                    break
                                else:
                                    print(f"  Error: Could not parse price")        
                else:
                    print(f"  Error: Could not find price on page")
        
        # Save workbook
        print(f"\n{'='*60}")
        print(f"Saving workbook...")
        wb.save(workbook_name)
        
        print(f"\nComplete!")
        print(f"Processed: {processed_count} Card Market entries")
        print(f"Updated: {updated_count} prices")
        print(datetime.now())

    finally:
        driver.quit()

if __name__ == "__main__":
    main()