#!/usr/bin/env python3
"""Amazon CreatorAPI 3.2 — Brettspiel-Deals auf amazon.de finden (verbessert).
Änderungen:
- item_count=50 (max), MAX_PAGES=10 (max)
- 15 Keywords statt 5 — deckt mehr Spieltypen ab
- Ohne min_saving_percent (Client-seitiger Filter, zuverlässiger)
- Zusätzlich: keyword-lose Browse-Node-Suche für alle Deals
"""

import argparse, os, re, time
from datetime import datetime

from amazon_creatorsapi import AmazonCreatorsApi, Country
from amazon_creatorsapi import models as m

# Configuration
CREDENTIAL_ID = "amzn1.application-oa2-client.91799968d0744e66950ea413659197d4"
CREDENTIAL_ID = "amzn1.application-oa2-client.91799968d0744e66950ea413659197d4"
CREDENTIAL_SECRET = "amzn1.oa2-cs.v1.4c41154ecfd1835e00879ad5c8060ef5cd3b209b06077c0af1d868b343cab955"
PARTNER_TAG = "60pro05-21"
BROWSE_NODE = "1290250031"  # Gesellschaftsspiele
COUNTRY = Country.DE
MAX_PAGES = 10
ITEMS_PER_PAGE = 50

# Breite Keyword-Abdeckung — 15 verschiedene Suchbegriffe
KEYWORDS = [
    "Brettspiel", "Kartenspiel", "Familienspiel", "Strategiespiel", "Partyspiel",
    "Kennerspiel", "Kinderspiel", "Würfelspiel", "Legespiel", "kooperativ",
    "Roll & Write", "Deckbuilding", "Worker Placement", "Drafting", "Puzzle",
]

RESOURCES = [
    m.SearchItemsResource.ITEM_INFO_DOT_TITLE,
    m.SearchItemsResource.IMAGES_DOT_PRIMARY_DOT_LARGE,
    m.SearchItemsResource.OFFERS_V2_DOT_LISTINGS_DOT_PRICE,
]


def search_amazon(api, keyword=None, page=1):
    try:
        kwargs = dict(
            browse_node_id=BROWSE_NODE,
            item_count=ITEMS_PER_PAGE,
            item_page=page,
            resources=RESOURCES,
        )
        if keyword:
            kwargs["keywords"] = keyword
        resp = api.search_items(**kwargs)
        time.sleep(1.1)
        return resp
    except Exception as e:
        print(f"  Error '{keyword or 'BROWSE'}' p{page}: {e}", flush=True)
        return None


def extract_deals(response):
    deals = []
    if not response or not response.items:
        return deals
    for item in response.items:
        try:
            title = str(item.item_info.title.display_value)
            image = ""
            if item.images and item.images.primary and item.images.primary.large:
                image = str(item.images.primary.large.url)
            asin = str(item.asin)

            if not item.offers_v2 or not item.offers_v2.listings:
                continue
            listing = item.offers_v2.listings[0]
            if not listing.price or not listing.price.money:
                continue

            price = float(listing.price.money.amount)
            list_price = None
            savings_pct = 0
            savings_eur = 0

            if listing.price.savings and listing.price.savings.money:
                savings_eur = float(listing.price.savings.money.amount)
                savings_pct = int(listing.price.savings.percentage)
            if listing.price.saving_basis and listing.price.saving_basis.money:
                list_price = float(listing.price.saving_basis.money.amount)

            # Client-seitiger Filter — zuverlässiger als min_saving_percent
            if savings_pct >= 10:
                deals.append({
                    "title": title, "image": image, "asin": asin,
                    "price": price, "list_price": list_price or price,
                    "savings_pct": savings_pct, "savings_eur": savings_eur,
                    "url": f"https://www.amazon.de/dp/{asin}?tag={PARTNER_TAG}",
                })
        except Exception:
            continue
    return deals


def generate_html(deals, output_path):
    seen = set()
    unique = []
    for d in deals:
        if d["asin"] not in seen:
            seen.add(d["asin"])
            unique.append(d)
    
    # === QUALITÄTSKONTROLLE: Nicht-Spiele herausfiltern ===
    # Blacklist: Produkte, die definitiv KEINE Brettspiele sind
    NON_GAME_PATTERNS = [
        # Elektronik & Gadgets
        r'\bAir\s*Tag\b', r'\bAirtag\b',
        r'\bGPS[-\s]Tracker\b', r'\bBluetooth[-\s]Tracker\b',
        r'\bKopfhörer\b', r'\bSmartwatch\b',
        # Software, digital, Steuer (NUR als eigenständiges Produkt)
        r'\bWISO\s+Steuer\b', r'\bSteuer\s*\d{4}\b',
        r'\bSteuererklärung\b', r'\bSteuersoftware\b',
        r'\bDigitaler\s+Download\b',
        r'\bAntivirus\b', r'\bAntiviren\b',
        # Bücher (explizit, nicht im Spielekontext)
        r'\bTaschenbuch\b', r'\bGebundene\s+Ausgabe\b',
        r'\bKindle\b', r'\bHörbuch\b',
        r'\bSchulbuch\b', r'\bLernheft\b', r'\bÜbungsbuch\b',
        r'\bVokabelheft\b', r'\bVokabeltrainer\b',
        # Medien (keine Spiele)
        r'\bBlu-ray\b',
        # Haushalt & Sonstiges
        r'\bNetzteil\b', r'\bLadegerät\b',
        # Sonstige Nicht-Spiele
        r'\bPolydraw\b', r'\bDrafting\s+Film\b', r'\bDrafting\s+Pad\b',
        r'\bBasic\s+Drafting\b',
        # Jigsaw-Puzzles (keine Brettspiele)
        r'\bPuzzle\s+\d+\s*Teile\b', r'\b\d+\s*Teile\s+Puzzle\b',
        r'\bJigsaw\s+Puzzle\b', r'\bPuzzle\s+\d+[.,]\d+\s*cm\b',
    ]
    
    filtered = []
    removed = []
    for d in unique:
        title_lower = d["title"].lower()
        is_non_game = False
        for pattern in NON_GAME_PATTERNS:
            if re.search(pattern, title_lower, re.IGNORECASE):
                is_non_game = True
                break
        if is_non_game:
            removed.append(d)
        else:
            filtered.append(d)
    
    if removed:
        print(f"  QC: {len(removed)} Nicht-Spiele entfernt:")
        for r in removed:
            print(f"    ✗ {r['title'][:80]}")
    
    unique = filtered
    # === ENDE QUALITÄTSKONTROLLE ===
    unique.sort(key=lambda x: x["savings_pct"], reverse=True)
    top = unique[:50]  # Show top 50 instead of 30

    now = datetime.now().strftime("%d.%m.%Y, %H:%M")
    cards = []
    for d in top:
        cards.append(f"""<div style="display:flex;gap:1rem;padding:1rem 0;border-bottom:1px solid #eee;">
<img src="{d['image']}" alt="" style="width:100px;height:100px;object-fit:contain;">
<div style="flex:1;"><strong>{d['title'][:120]}</strong><br>
<span style="color:#b12704;font-size:1.2rem;font-weight:bold;">{d['price']:.2f} €</span>
<span style="text-decoration:line-through;color:#999;margin-left:0.5rem;">UVP {d['list_price']:.2f} €</span>
<span style="background:#b12704;color:#fff;padding:2px 6px;border-radius:3px;margin-left:0.5rem;font-size:0.85rem;">-{d['savings_pct']}%</span>
<span style="color:#b12704;margin-left:0.3rem;">({d['savings_eur']:.2f} € gespart)</span><br>
<a href="{d['url']}" target="_blank" style="color:#007185;">Zu Amazon →</a></div></div>""")

    html = f"""<!DOCTYPE html><html lang="de"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Brettspiel-Angebote — Amazon Deals</title>
<style>body{{margin:0;padding:0;background:#f9f7f4;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;color:#2c2416;line-height:1.6}}
article{{max-width:720px;margin:0 auto;padding:2rem 1.5rem;background:#fff;box-shadow:0 2px 12px rgba(0,0,0,0.06)}}
h1{{font-size:1.5rem;color:#1a1a1a}}.meta{{color:#999;font-size:.85rem;margin-bottom:1.5rem}}
a{{color:#007185;text-decoration:none}}a:hover{{text-decoration:underline}}</style></head><body><article>
<h1>Brettspiel-Angebote auf Amazon</h1><p class="meta">Stand: {now} · Mindestens 10 % Rabatt · Preise inkl. MwSt. · {len(unique)} Deals gefunden (Top 50)</p>
{''.join(cards) if cards else '<p>Keine reduzierten Brettspiele gefunden.</p>'}
<p class="meta" style="margin-top:2rem;">Preise und Verfügbarkeit können sich schnell ändern. Über die Links ({PARTNER_TAG}) kauft ihr zum gleichen Preis — Amazon zahlt eine kleine Provision.</p>
</article></body></html>"""
    with open(output_path, 'w') as f:
        f.write(html)
    return len(top)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--limit', type=int, default=50)
    parser.add_argument('--output', type=str, default=None)
    args = parser.parse_args()

    if args.output is None:
        args.output = os.path.expanduser(f"~/workspace/amazon_deals_{datetime.now().strftime('%Y-%m-%d')}.html")

    api = AmazonCreatorsApi(
        CREDENTIAL_ID, CREDENTIAL_SECRET, "3.2", PARTNER_TAG,
        country=COUNTRY, throttling=1.0
    )
    print(f"Connected to CreatorAPI (DE) — {len(KEYWORDS)} Keywords, {ITEMS_PER_PAGE}/page, {MAX_PAGES} pages")

    all_deals = []

    # 1. Keyword searches
    for kw in KEYWORDS:
        kw_deals = 0
        for page in range(1, MAX_PAGES + 1):
            resp = search_amazon(api, kw, page)
            if not resp:
                break
            deals = extract_deals(resp)
            all_deals.extend(deals)
            kw_deals += len(deals)
            # Stop if fewer items returned (end of results)
            if resp.items and len(resp.items) < ITEMS_PER_PAGE:
                break
        print(f"  '{kw}': {kw_deals} Deals gesamt")

    # 2. Browse ohne Keywords (catch-all)
    print(f"  'BROWSE' (keyword-frei): ", end="", flush=True)
    browse_deals = 0
    for page in range(1, MAX_PAGES + 1):
        resp = search_amazon(api, keyword=None, page=page)
        if not resp:
            break
        deals = extract_deals(resp)
        all_deals.extend(deals)
        browse_deals += len(deals)
        if resp.items and len(resp.items) < ITEMS_PER_PAGE:
            break
    print(f"{browse_deals} Deals")

    count = generate_html(all_deals, args.output)
    print(f"\n{count} reduzierte Brettspiele (Top 50) → {args.output}")
    print(f"Link: http://185.162.249.159:8890/{os.path.basename(args.output)}?key=br3ttsp1el-n3ws-2026")


if __name__ == "__main__":
    main()
