#!/usr/bin/env python3
"""Scrape Gladbach-focused football news from German sources."""

import requests
from bs4 import BeautifulSoup
import json
import time
import re

HEADERS = {
    'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7',
}

GLADBACH_KW = [
    'gladbach', 'borussia', 'mönchengladbach', 'fohlen', 'fohlenelf',
    'borussia park', 'niederrhein', 'borussen',
    'elvedi', 'plea', 'honorat', 'neuhaus', 'weigl', 'koné',
    'scally', 'oultara', 'friedrich', 'itakura', 'ngoumou',
    'cvančara', 'civancara', 'ranos', 'hack',
    'reitz', 'netz', 'wöber', 'woeber', 'kleindienst',
    'seoane', 'virkus',
]

def fetch_url(url, retries=2):
    for attempt in range(retries + 1):
        try:
            resp = requests.get(url, headers=HEADERS, timeout=20)
            resp.raise_for_status()
            resp.encoding = resp.apparent_encoding or 'utf-8'
            return resp
        except Exception as e:
            if attempt < retries:
                time.sleep(2)
            else:
                print(f"  FAILED: {url} — {e}")
                return None

def clean_text(text):
    return re.sub(r'\s+', ' ', text).strip()

def is_recent_date(date_str):
    patterns = [
        r'01\.06\.2026', r'02\.06\.2026',
        r'1\.\s*Juni\s*2026', r'2\.\s*Juni\s*2026',
        r'01\.06\.26', r'02\.06\.26',
        r'2026-06-01', r'2026-06-02',
        r'vor \d+ Stunden', r'vor \d+ Minuten',
    ]
    for pat in patterns:
        if re.search(pat, date_str, re.IGNORECASE):
            return True
    return False

def has_gladbach_keyword(text, min_hits=1):
    text_lower = text.lower()
    hits = sum(1 for kw in GLADBACH_KW if kw in text_lower)
    return hits >= min_hits

def extract_article_text(soup):
    selectors = [
        'article', '.article-content', '.article-body', '.post-content',
        '.entry-content', '.content', '.story-body', '.article__body',
        '.article-text', '.news-text', 'main', '.main-content',
        '[itemprop="articleBody"]', '.article__content', '.post__content',
        '.single-content', '#article-content',
    ]
    for sel in selectors:
        elem = soup.select_one(sel)
        if elem:
            for unwanted in elem.find_all(['script', 'style', 'nav', 'aside', 'footer', 'header', 'iframe', 'form']):
                unwanted.decompose()
            text = elem.get_text(separator=' ', strip=True)
            text = clean_text(text)
            if len(text) > 200:
                return text
    paragraphs = soup.find_all('p')
    texts = [clean_text(p.get_text()) for p in paragraphs if len(p.get_text().strip()) > 50]
    if texts:
        return ' '.join(texts)
    body = soup.find('body')
    if body:
        for unwanted in body.find_all(['script', 'style', 'nav', 'footer', 'header', 'iframe']):
            unwanted.decompose()
        return clean_text(body.get_text(separator=' ', strip=True))
    return ""

def extract_date(soup):
    date_patterns = [
        ('meta[property="article:published_time"]', 'content'),
        ('meta[name="date"]', 'content'),
        ('meta[name="pubdate"]', 'content'),
        ('time', 'datetime'),
        ('time[datetime]', 'datetime'),
    ]
    for selector, attr in date_patterns:
        elem = soup.select_one(selector)
        if elem:
            val = elem.get(attr, '') if attr else elem.get_text(strip=True)
            if val and len(val) > 5:
                return val
    text = soup.get_text()
    m = re.search(r'(\d{1,2}\.\s*\d{1,2}\.\s*(?:20)?2[456])', text)
    return m.group(1) if m else ""

def generic_scrape(name, base_urls, url_filter=None, title_cleanup=None, gladbach_check=True):
    """Generic scraper for a news site."""
    print(f"\n{'='*60}\nSCRAPING: {name}\n{'='*60}")
    results = []
    
    for base_url in base_urls:
        print(f"  Trying: {base_url}")
        resp = fetch_url(base_url)
        if not resp:
            continue
        
        soup = BeautifulSoup(resp.text, 'html.parser')
        links = soup.find_all('a', href=True)
        article_urls = set()
        
        for link in links:
            href = link['href']
            if not href or href.startswith('#') or href.startswith('javascript:') or href.startswith('mailto:'):
                continue
            if href.endswith(('.jpg', '.png', '.gif', '.pdf', '.css', '.js', '.ico')):
                continue
            
            # Build full URL
            if href.startswith('http'):
                full_url = href
            elif href.startswith('//'):
                full_url = 'https:' + href
            elif href.startswith('/'):
                # Extract domain from base_url
                domain = re.match(r'https?://[^/]+', base_url)
                if domain:
                    full_url = domain.group(0) + href
                else:
                    continue
            else:
                continue
            
            if full_url in article_urls:
                continue
            
            # Apply filter if provided
            if url_filter:
                if url_filter(full_url):
                    article_urls.add(full_url)
            else:
                article_urls.add(full_url)
        
        print(f"  Found {len(article_urls)} potential article URLs (sampling first 30)")
        
        for art_url in list(article_urls)[:30]:
            print(f"    Fetching: {art_url}")
            art_resp = fetch_url(art_url)
            if not art_resp:
                continue
            
            art_soup = BeautifulSoup(art_resp.text, 'html.parser')
            
            # Extract title
            title = None
            title_elem = art_soup.find('title')
            if title_elem:
                title = clean_text(title_elem.get_text())
                if title_cleanup:
                    title = title_cleanup(title)
            if not title or len(title) < 15:
                h1 = art_soup.find('h1')
                if h1:
                    title = clean_text(h1.get_text())
            if not title or len(title) < 15:
                continue
            
            date_str = extract_date(art_soup)
            full_text = extract_article_text(art_soup)
            
            if not full_text or len(full_text) < 100:
                print(f"      Skipping (no usable text)")
                continue
            
            if date_str and not is_recent_date(date_str):
                print(f"      Skipping (date: {date_str})")
                continue
            
            if gladbach_check:
                combined = (title + ' ' + full_text).lower()
                if not has_gladbach_keyword(combined, min_hits=1):
                    print(f"      Not Gladbach-related, skipping")
                    continue
            
            print(f"      ✓ FOUND: {title[:80]}")
            results.append({
                'source': name,
                'title': title,
                'url': art_url,
                'date': date_str or 'Kein Datum gefunden',
                'full_text': full_text[:3000],
            })
            
            if len(results) >= 2:
                break
        
        if results:
            break
    
    return results

def main():
    all_results = []
    
    # 1. torfabrik.de
    all_results.extend(generic_scrape(
        'torfabrik.de',
        ['https://www.torfabrik.de/', 'https://www.torfabrik.de/borussia-moenchengladbach/'],
        url_filter=lambda u: 'torfabrik.de' in u,
        title_cleanup=lambda t: re.sub(r'\s*[-–|]\s*[Tt]orfabrik.*$', '', t).strip(),
    ))
    
    # 2. fohlen-hautnah.de
    all_results.extend(generic_scrape(
        'fohlen-hautnah.de',
        ['https://www.fohlen-hautnah.de/'],
        url_filter=lambda u: 'fohlen-hautnah.de' in u,
        title_cleanup=lambda t: re.sub(r'\s*[-–|]\s*[Ff]ohlen[-\s]*[Hh]autnah.*$', '', t).strip(),
        gladbach_check=False,  # All articles are Gladbach-related
    ))
    
    # 3. gladbachlive.de
    all_results.extend(generic_scrape(
        'gladbachlive.de',
        ['https://www.gladbachlive.de/', 'https://www.gladbachlive.de/news/'],
        url_filter=lambda u: 'gladbachlive.de' in u,
        title_cleanup=lambda t: re.sub(r'\s*[-–|]\s*[Gg]ladbach[Ll]ive.*$', '', t).strip(),
    ))
    
    # 4. kicker.de
    all_results.extend(generic_scrape(
        'kicker.de',
        ['https://www.kicker.de/borussia-moenchengladbach/news', 'https://www.kicker.de/bundesliga/aktuell'],
        url_filter=lambda u: 'kicker.de' in u and any(kw in u.lower() for kw in ['gladbach', 'borussia-mg', 'bundesliga', 'news', 'transfer']),
        title_cleanup=lambda t: re.sub(r'\s*[-–|]\s*[Kk]icker.*$', '', t).strip(),
    ))
    
    # 5. sportschau.de (general Bundesliga, no strict Gladbach filter)
    all_results.extend(generic_scrape(
        'sportschau.de',
        ['https://www.sportschau.de/fussball/bundesliga/'],
        url_filter=lambda u: 'sportschau.de' in u and '/fussball/' in u,
        title_cleanup=lambda t: re.sub(r'\s*[-–|]\s*[Ss]portschau.*$', '', t).strip(),
        gladbach_check=False,
    ))
    
    # 6. fussballtransfers.com
    all_results.extend(generic_scrape(
        'fussballtransfers.com',
        ['https://www.fussballtransfers.com/bundesliga', 'https://www.fussballtransfers.com/'],
        url_filter=lambda u: 'fussballtransfers.com' in u,
        title_cleanup=lambda t: re.sub(r'\s*[-–|]\s*[Ff]ussball\s*[Tt]ransfers.*$', '', t).strip(),
    ))
    
    # Deduplicate by URL
    seen_urls = set()
    deduped = []
    for r in all_results:
        if r['url'] not in seen_urls:
            seen_urls.add(r['url'])
            deduped.append(r)
    
    # Prioritize: Gladbach articles first (with 2+ keyword hits), then the rest
    gladbach_heavy = [r for r in deduped if has_gladbach_keyword(r['title'] + ' ' + r['full_text'], min_hits=2)]
    gladbach_light = [r for r in deduped if r not in gladbach_heavy and has_gladbach_keyword(r['title'] + ' ' + r['full_text'], min_hits=1)]
    other = [r for r in deduped if r not in gladbach_heavy and r not in gladbach_light]
    
    # Take 5: prefer heavy Gladbach, then light Gladbach, then other
    final = gladbach_heavy + gladbach_light + other
    final = final[:5]
    
    print("\n\n" + "=" * 60)
    print(f"FINAL RESULTS: {len(final)} articles")
    print("=" * 60)
    
    for i, r in enumerate(final, 1):
        print(f"\n--- Artikel {i} ---")
        print(f"Quelle: {r['source']}")
        print(f"Titel: {r['title']}")
        print(f"Datum: {r['date']}")
        print(f"URL: {r['url']}")
        print(f"Textlänge: {len(r['full_text'])} Zeichen")
    
    with open('/home/hermes/workspace/gladbach_news.json', 'w', encoding='utf-8') as f:
        json.dump(final, f, ensure_ascii=False, indent=2)
    
    print(f"\nResults saved to /home/hermes/workspace/gladbach_news.json")
    return final

if __name__ == '__main__':
    main()
