#!/usr/bin/env python3
"""Spiele-Offensive Top-30 mit korrekten Bildern aus den Listing-Seiten."""
import re, sys, urllib.request
from datetime import datetime
from html import unescape

UA = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36"
NOW = datetime.now().strftime("%d.%m.%Y %H:%M")
PID = "505"
OUT = "/home/hermes/workspace/spiele_offensive_top30.html"

def fetch(url, timeout=15):
    req = urllib.request.Request(url, headers={"User-Agent": UA})
    with urllib.request.urlopen(req, timeout=timeout) as r:
        raw = r.read()
        try: return raw.decode("utf-8")
        except: return raw.decode("iso-8859-1", errors="replace")

def fix(s):
    for a,b in [("Ã¼","ü"),("Ã¶","ö"),("Ã¤","ä"),("ÃŸ","ß"),("Ãœ","Ü"),("Ã„","Ä"),("Ã–","Ö"),("Ã©","é")]:
        s = s.replace(a,b)
    return unescape(s.replace("&amp;","&").replace("&quot;",'"')).strip()

# ── Build aid→image_filename map from Sonderangebote listing pages ──
# The HTML pattern: <a onclick="registerItemSelection(dataLayer, AID, …)" …><center><img src="https://mediaservice…/size=100x100/FILENAME" …></center></a>
print("Scraping Sonderangebote...", file=sys.stderr)
aid_img = {}

for page in range(10):
    try:
        h = fetch(f"https://www.spiele-offensive.de/Kat/Sonderangebote.html?sse={page}", 15)
    except Exception as e:
        print(f"  p{page}: {e}", file=sys.stderr); continue

    # Clean regex: capture aid from onclick + filename from img src
    for m in re.finditer(
        r'registerItemSelection\(dataLayer,\s*(\d+)\s*,.*?'
        r'<img src="https://mediaservice\.happyshops\.com/ANY/Article/\d+/size=100x100/([^"]+)"',
        h, re.DOTALL
    ):
        aid, fn = m.group(1), m.group(2).strip()
        fn = fn.split("?")[0]
        if aid not in aid_img:
            aid_img[aid] = fn

print(f"  Map: {len(aid_img)} entries", file=sys.stderr)

# ── Also scrape individual product pages for any missing ──
def get_img_from_product_page(aid):
    """Fallback: fetch product detail page and extract main image filename."""
    try:
        h = fetch(f"https://www.spiele-offensive.de/index.php?cmd=artikel_anzeigen&aid={aid}", 10)
        # Main product image: class='abildg' src='.../width=450/FILENAME'
        m = re.search(r"class='abildg'[^>]*src='[^']*/([^/\"'\s?]+)'", h)
        if m:
            return m.group(1).strip()
        # Alternative: any width=450 image
        m = re.search(r"width=450/([^\"'\s?]+)", h)
        if m:
            return m.group(1).strip()
        # Last resort: first mediaservice image that's not 100x100
        for m in re.finditer(r'src="https://mediaservice[^"]*/([^/"\s?]+)"', h):
            fn = m.group(1)
            if 'size=100x100' not in fn and len(fn) > 3:
                return fn.strip()
    except:
        pass
    return None

# ── Extract deals from existing deals HTML ──
print("Reading existing deals...", file=sys.stderr)
with open("/home/hermes/workspace/spiele_offensive_deals.html") as f:
    html = f.read()

deals = []
for m in re.finditer(
    r'<div class="card-name">([^<]+)</div>.*?'
    r'<div class="card-badge"[^>]*>([^<]+)</div>.*?'
    r'<span class="card-old">([^<]*)</span>.*?'
    r'<span class="card-new">([^<]+)</span>.*?'
    r'<a href="[^"]*aid=(\d+)',
    html, re.DOTALL
):
    name = m.group(1).strip()
    badge = m.group(2).strip()
    old = m.group(3).strip().replace(" €", "")
    new = m.group(4).strip().replace(" €", "")
    aid = m.group(5).strip()
    rabatt = int(re.search(r'(\d+)', badge).group(1)) if re.search(r'(\d+)', badge) else 0
    deals.append({"name": name, "rabatt": rabatt, "old_price": old, "new_price": new, "aid": aid})

# Filter & sort
SKIP = ['puzzle', 'jigsaw', 'wundertüte', 'rätselpuzzle', 'tragetasche']
deals = [d for d in deals if not any(w in d["name"].lower() for w in SKIP)]
seen = set()
uniq = []
for d in deals:
    if d["aid"] not in seen:
        seen.add(d["aid"])
        uniq.append(d)
uniq.sort(key=lambda d: -d["rabatt"])
top30 = uniq[:30]

# ── Ensure all products have images ──
for d in top30:
    aid = d["aid"]
    if aid not in aid_img:
        fn = get_img_from_product_page(aid)
        if fn:
            aid_img[aid] = fn
            print(f"  Fallback {aid}: {fn}", file=sys.stderr)
        else:
            print(f"  NO IMAGE: {aid} - {d['name'][:50]}", file=sys.stderr)

# ── Generate HTML ──
def img_url(aid, fn):
    padded = f"{int(aid):012d}"
    return f"https://mediaservice.happyshops.com/ANY/Article/{padded}/width=200/{fn}"

cards = ""
for d in top30:
    name = d["name"]
    aid = d["aid"]
    old = d["old_price"]
    new = d["new_price"]
    rabatt = d["rabatt"]
    
    try:
        saved = float(old.replace(",",".")) - float(new.replace(",","."))
        saved_s = f"({saved:.2f} € gespart)".replace(".", ",")
    except:
        saved_s = ""
    
    old_h = f'<span class="cold">UVP {old} €</span>'
    bc = "#b12704" if rabatt >= 80 else ("#e63946" if rabatt >= 60 else "#cc0c39")
    
    if aid in aid_img:
        isrc = img_url(aid, aid_img[aid])
        igh = f'<img src="{isrc}" alt="" class="dimg" loading="lazy" onerror="this.style.display=\'none\'">'
    else:
        igh = '<div class="dimg" style="display:flex;align-items:center;justify-content:center;color:#ccc;font-size:2rem;background:#eee">?</div>'
    
    cards += f"""<div class="d">
{igh}
<div class="dinfo">
<span class="dname">{name}</span>
<span class="dprice">{new} €</span>{old_h}
<span class="dbadge" style="background:{bc}">-{rabatt}%</span>
<span class="dsave">{saved_s}</span>
<a href="https://www.spiele-offensive.de/index.php?cmd=artikel_anzeigen&aid={aid}&pid={PID}" target="_blank" class="dlink">Zu Spiele-Offensive →</a>
</div></div>
"""

out_html = f"""<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Top 30 Brettspiel-Angebote — Spiele-Offensive.de</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,.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}}
.d{{display:flex;gap:1rem;padding:1rem 0;border-bottom:1px solid #eee;align-items:flex-start}}
.dimg{{width:100px;height:100px;object-fit:contain;flex-shrink:0;border-radius:4px;background:#f5f5f5}}
.dinfo{{flex:1;min-width:0}}
.dname{{font-weight:600;color:#1a1a1a;font-size:.95rem;display:block;line-height:1.3;margin-bottom:3px}}
.dprice{{color:#b12704;font-size:1.2rem;font-weight:bold}}
.cold{{text-decoration:line-through;color:#999;margin-left:.5rem;font-size:.9rem}}
.dbadge{{color:#fff;padding:2px 6px;border-radius:3px;margin-left:.5rem;font-size:.85rem;font-weight:600}}
.dsave{{color:#b12704;margin-left:.3rem;font-size:.9rem}}
.dlink{{display:inline-block;margin-top:4px;color:#e63946;font-size:.9rem;font-weight:500}}
.dlink:hover{{text-decoration:underline}}
.footer{{margin-top:2rem;padding-top:1rem;border-top:1px solid #eee;font-size:.85rem;color:#888}}
</style>
</head>
<body>
<article>
<h1>Top 30 Brettspiel-Angebote auf Spiele-Offensive.de</h1>
<p class="meta">Stand: {NOW} · Sortiert nach Rabatt · Preise inkl. MwSt. · Affiliate-Links (PID {PID}) · Bilder: HappyShops CDN</p>

{cards}

<div class="footer">
<p>Alle Preise und Verfügbarkeiten zum Zeitpunkt der Erhebung. Zwischenverkauf und Preisänderungen vorbehalten.</p>
<p>Dieser Beitrag enthält Affiliate-Links. Bei einem Kauf über diese Links erhalten wir eine kleine Provision — für dich entstehen keine Mehrkosten.</p>
</div>
</article></body></html>"""

with open(OUT, "w") as f:
    f.write(out_html)

import subprocess
c = subprocess.run(["grep", "-c", "mediaservice", OUT], capture_output=True, text=True)
imgs = c.stdout.strip()
print(f"Done: {len(top30)} deals, {imgs} with images, {len(out_html)} bytes", file=sys.stderr)
print(f"FILE:{OUT}")
