#!/usr/bin/env python3
"""Amazon CreatorAPI 3.2 — Kinderspiele-Deals auf amazon.de finden.
NUR Kinderspiele behalten, Non-Games entfernen."""

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

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

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 = 8
ITEMS_PER_PAGE = 50

KINDERSPIEL_KEYWORDS = [
    "Kinderspiel Brettspiel",
    "Kinderspiel ab 3 Jahre",
    "Kinderspiel ab 4 Jahre",
    "Kinderspiel ab 5 Jahre",
    "Kinderspiel ab 6 Jahre",
    "Kinderspiel ab 7 Jahre",
    "Mitbringspiel",
    "Vorschulspiel",
    "Lernspiel Kinder",
    "Gedächtnisspiel Kinder",
    "Würfelspiel Kinder",
    "Kinderkartenspiel",
    "Bluey Spiel",
    "Paw Patrol Spiel",
    "Peppa Pig Spiel",
    "Sendung mit der Maus Spiel",
    "Dobble",
    "Uno Junior",
    "Lotti Karotti",
    "Obstgarten Spiel",
]

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

# Patterns für NON-Games (entfernen)
NON_GAME_PATTERNS = [
    r'\btragetasche\b', r'\bau(fbewahr|fbewahrung)\b', r'\bpuzzle\b',
    r'\bjigsaw\b', r'\bairtag\b', r'\bwiso\s+steuer\b', r'\bblu-?ray\b',
    r'\bdvd\b', r'\binsert\b', r'\borgani[sz]er\b', r'\bwellness\b',
    r'\bclean\s+slate\b', r'\btaschenbuch\b', r'\bcd\b', r'\bbuch\b',
    r'\bhandgepäck\b', r'\beurowings\b', r'\bryanair\b', r'\bsoaker\b',
    r'\bnerf\b', r'\bkrang\b', r'\bdr\.?\s*rahm\b',
    r'\d{2,4}\s*teilig',  # Puzzles mit Stückzahl
    r'\d{3,4}\s*pc\b',    # Jigsaw piece count
]

NON_GAME_SIMPLE = [
    'tragetasche', 'aufbewahrung', 'airtag', 'wiso', 'blu-ray', 'bluray',
    'wellness', 'clean slate', 'dr. rahm', 'krang', 'handgepäck',
    'eurowings', 'ryanair', 'soaker', 'nerf', 'taschenbuch',
    'insert', 'organizer', 'upgrade kit',
]

def search_amazon(api, keyword, 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}' p{page}: {e}", flush=True)
        return None

def is_nongame(title):
    """Check if title is a non-game product."""
    tl = title.lower()
    # Simple check
    for bad in NON_GAME_SIMPLE:
        if bad in tl:
            return True
    # Stückzahl-Puzzle check: "1000 Teile", "500-teilig" etc.
    if re.search(r'\b(500|1000|1500|2000)\s*[tT]eil', tl):
        return True
    return False

def is_kinderspiel(title):
    """Check if title is a genuine children's game."""
    tl = title.lower()
    # Age markers
    if re.search(r'ab\s+[3-8]\s+jahr', tl):
        return True
    # Children's game markers
    kind_markers = [
        'kinderspiel', 'mitbringspiel', 'vorschul', 'lernspiel',
        'gedächtnisspiel', 'kinderkartenspiel', 'würfelspiel',
        'junior', 'kids', 'kinder',
        'bluey', 'paw patrol', 'peppa pig', 'sendung mit der maus',
        'monsterjäger', 'pupsparade', 'sagaland', 'verrückte labyrinth',
        'paletti spaghetti', 'tempo kleine schnecke', 'dobble',
        'uno junior', 'lotti karotti', 'obstgarten',
        'halli galli', 'zicke zacke', 'leo muss zum friseur',
        'make n break', 'make \'n\' break', 'memo', 'memory',
    ]
    for marker in kind_markers:
        if marker in tl:
            return True
    return False

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)

            # QC: Non-Games entfernen
            if is_nongame(title):
                continue

            # QC: Nur Kinderspiele behalten
            if not is_kinderspiel(title):
                continue

            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)

            # Niedrigere Schwelle für Kinderspiele (auch kleine Rabatte)
            if savings_pct > 0:
                if list_price is None:
                    list_price = price
                deals.append({
                    "title": title, "image": image, "asin": asin,
                    "price": price, "list_price": list_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 guess_age_group(title):
    """Guess age group from title."""
    tl = title.lower()
    if re.search(r'ab\s+3\s+jahr', tl):
        return "3+"
    if re.search(r'ab\s+4\s+jahr', tl):
        return "4+"
    if re.search(r'ab\s+5\s+jahr', tl):
        return "5+"
    if re.search(r'ab\s+6\s+jahr', tl):
        return "6+"
    if re.search(r'ab\s+7\s+jahr', tl):
        return "7+"
    if 'mitbringspiel' in tl:
        return "Mitbringspiele"
    if re.search(r'ab\s+8\s+jahr', tl):
        return "8+"
    # Fallback: check for junior/kids markers
    if 'junior' in tl or 'kids' in tl:
        return "Mitbringspiele"
    return "Allgemein"

AGE_ORDER = ["3+", "4+", "5+", "6+", "7+", "8+", "Mitbringspiele", "Allgemein"]

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)
    unique.sort(key=lambda x: x["savings_pct"], reverse=True)
    top = unique[:20]

    # Group by age
    groups = {}
    for d in top:
        age = guess_age_group(d["title"])
        if age not in groups:
            groups[age] = []
        groups[age].append(d)

    now = datetime.now().strftime("%d.%m.%Y, %H:%M")
    sections = []
    for age in AGE_ORDER:
        if age not in groups:
            continue
        items = groups[age]
        age_labels = {
            "3+": "Für die Kleinsten (ab 3 Jahre)",
            "4+": "Ab 4 Jahre",
            "5+": "Ab 5 Jahre",
            "6+": "Ab 6 Jahre",
            "7+": "Ab 7 Jahre",
            "8+": "Ab 8 Jahre",
            "Mitbringspiele": "Mitbringspiele",
            "Allgemein": "Weitere Kinderspiele",
        }
        label = age_labels.get(age, age)
        cards = []
        for d in items:
            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;" loading="lazy">
<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" rel="noopener" style="color:#007185;">Zu Amazon →</a></div></div>""")
        sections.append(f"<h2>{label}</h2>\n{''.join(cards)}")

    count_info = f"{len(top)} Spiele in {len(groups)} Altersgruppen"

    html = f"""<!DOCTYPE html><html lang="de"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Kinderspiele-Angebote auf Amazon</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}}h2{{font-size:1.2rem;color:#20228a;margin-top:2rem;padding-bottom:0.5rem;border-bottom:2px solid #20228a}}
.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>Kinderspiele-Angebote auf Amazon</h1><p class="meta">Stand: {now} · {count_info} · Preise inkl. MwSt.</p>
{''.join(sections) if sections else '<p>Keine reduzierten Kinderspiele 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>
<p style="font-size:0.8rem;color:#999;text-align:center;margin-top:1rem;">Brettspiel-News.de · (C) liegt beim jeweiligen Rechteinhaber</p>
</article></body></html>"""
    with open(output_path, 'w') as f:
        f.write(html)
    return len(top), groups

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

    if args.output is None:
        args.output = os.path.expanduser(f"~/workspace/kinderspiele_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) — Kinderspiele-Suche")
    print(f"Keywords: {len(KINDERSPIEL_KEYWORDS)} · {MAX_PAGES} Seiten à {ITEMS_PER_PAGE}\n")

    all_deals = []
    for kw in KINDERSPIEL_KEYWORDS:
        for page in range(1, MAX_PAGES + 1):
            resp = search_amazon(api, kw, page)
            if resp:
                deals = extract_deals(resp)
                all_deals.extend(deals)
                total = resp.total_result_count if hasattr(resp, 'total_result_count') else '?'
                if deals:
                    names = [d['title'][:50] for d in deals]
                    print(f"  {kw} p{page}: {len(deals)} Kinderspiele (total: {total})")
                    for n in names:
                        print(f"    → {n}")
                else:
                    print(f"  {kw} p{page}: 0 Kinderspiele (total: {total})")
        # Early exit if we have enough
        if len(all_deals) >= args.limit * 2:
            break

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

    # Print summary for Joomla article building
    print(f"\n=== SUMMARY ===")
    print(f"Total: {count} Spiele")
    for age in AGE_ORDER:
        if age in groups:
            print(f"  {age}: {len(groups[age])} Spiele")
            for d in groups[age]:
                print(f"    {d['savings_pct']}% | {d['price']:.2f}€ | {d['title'][:80]} | ASIN:{d['asin']}")

if __name__ == "__main__":
    main()
