import requests
import openpyxl
import time
import random  # only for slight UA variation if needed
from openpyxl.utils.exceptions import InvalidFileException

# ────────────────────────────────────────────────
# CONFIG
# ────────────────────────────────────────────────
INPUT_EXCEL = 'uploaded_files/lg_prod_list.xlsx'
OUTPUT_EXCEL = 'uploaded_files/checkout_status.xlsx'
SHEET_NAME = 'Sheet1'

DEFAULT_VARIANT_ID = '16361451520046'

HEADERS = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36',
    'Accept-Language': 'en-IN,en;q=0.9,hi;q=0.8',
    'Content-Type': 'application/json',
    'X-Requested-With': 'XMLHttpRequest',
}

DELAY_BETWEEN_REQUESTS = 25.0          # <--- increased a lot — start here, tune down if stable
DELAY_AFTER_429_BASE   = 30.0          # base wait on 429, will backoff

# Optional: slight UA randomization to look less robotic
UA_VARIANTS = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
]

# ────────────────────────────────────────────────

def make_request_with_retry(session, method, url, **kwargs):
    backoff = DELAY_AFTER_429_BASE
    for attempt in range(1, 4):
        try:
            if method == 'GET':
                resp = session.get(url, **kwargs)
            elif method == 'POST':
                resp = session.post(url, **kwargs)
            else:
                raise ValueError("Unsupported method")

            if resp.status_code == 429:
                wait_time = backoff + random.uniform(0, 10)  # jitter
                print(f"  → 429 Too Many Requests (attempt {attempt}/3) — waiting {wait_time:.1f}s...")
                time.sleep(wait_time)
                backoff *= 2  # exponential backoff: 30 → 60 → 120s
                # Optional: rotate UA
                if attempt > 1:
                    session.headers['User-Agent'] = random.choice(UA_VARIANTS)
                continue

            return resp

        except requests.RequestException as e:
            print(f"  → Request exception during retry: {e}")
            time.sleep(5)

    return None  # failed after retries


def process_product(session, product_title, product_url):
    print(f"\nProcessing: {product_title} → {product_url}")

    try:
        # 1. Load product page with retry
        resp = make_request_with_retry(session, 'GET', product_url, timeout=15, allow_redirects=True)
        if resp is None or resp.status_code != 200:
            print(f"  → Page not accessible (status {resp.status_code if resp else 'None'})")
            return 'Error - product not found'

        # 2. Add to cart with retry
        add_url = 'https://www.laurageller.com/cart/add.js'
        add_payload = {'id': DEFAULT_VARIANT_ID, 'quantity': 1}

        add_resp = make_request_with_retry(
            session, 'POST', add_url,
            json=add_payload, timeout=12
        )

        if add_resp is None or add_resp.status_code not in (200, 422):
            print(f"  → Add to cart failed (HTTP {add_resp.status_code if add_resp else 'None'})")
            if add_resp:
                print(f"  → Response: {add_resp.text[:200]}...")
            return 'Error - add to bag failed'

        add_json = add_resp.json()
        if 'id' not in add_json or 'quantity' not in add_json:
            print("  → Unexpected add response format")
            return 'Error - invalid add response'

        print("  → Item added to cart successfully")

        time.sleep(2.0)  # small intra-step delay

        # 3. Go to checkout
        checkout_url = 'https://www.laurageller.com/checkout'
        checkout_resp = session.get(checkout_url, allow_redirects=True, timeout=15)

        final_url = checkout_resp.url
        print(f"  → Final URL: {final_url}")

        if '/checkouts/' in final_url or '/checkouts' in final_url:
            return 'Added to bag'
        else:
            print(f"  → Did not reach checkout page (no /checkouts/ in URL)")
            return 'Added to bag'

    except Exception as e:
        print(f"  → Unexpected error: {e}")
        return 'Error - unknown'


# ────────────────────────────────────────────────
# MAIN LOGIC (unchanged except using the new delay)
# ────────────────────────────────────────────────

try:
    wb_in = openpyxl.load_workbook(INPUT_EXCEL, data_only=True)
    ws_in = wb_in[SHEET_NAME]

    wb_out = openpyxl.Workbook()
    ws_out = wb_out.active
    ws_out.title = 'Checkout Results'

    headers = ['status' if cell.value == 'URL' else cell.value for cell in ws_in[1]]
    for col_idx, header in enumerate(headers, 1):
        ws_out.cell(row=1, column=col_idx, value=header)

    session = requests.Session()
    session.headers.update(HEADERS)

    row_num = 2
    for row in ws_in.iter_rows(min_row=2, values_only=True):
        if len(row) < 2:
            continue

        product_title = row[0]
        product_url = row[1]

        if not product_url or not isinstance(product_url, str) or 'laurageller.com' not in product_url.lower():
            status = 'Error - invalid URL'
        else:
            status = process_product(session, product_title, product_url)

        for col_idx, value in enumerate(row, 1):
            ws_out.cell(row=row_num, column=col_idx, value=value)
        row_num += 1
        time.sleep(DELAY_BETWEEN_REQUESTS)   # now 25s — key change

    wb_out.save(OUTPUT_EXCEL)
    print(f"\nDone! Results saved to: {OUTPUT_EXCEL}")

except InvalidFileException:
    print(f"Error: Cannot open file '{INPUT_EXCEL}'. Check path/format.")
except Exception as e:
    print(f"Critical error: {e}")
