"""
SportyBet Nigeria scraper.

Endpoint discovered via Playwright network interception on sportybet.com/ng/sport/football
Requires _t (unix ms timestamp) query param — the API is open once the timestamp is added.
"""
import time
import logging
from datetime import datetime
from typing import List, Optional

from scrapers.base import BaseScraper
from core.models import Event, Outcome

logger = logging.getLogger(__name__)

BASE_URL = "https://www.sportybet.com/api/ng/factsCenter/pcUpcomingEvents"

# Market IDs discovered from browser network tab
SPORT_CONFIG = {
    'football': {
        'sport_id':  'sr%3Asport%3A1',
        'market_ids': '1%2C18%2C10%2C29%2C11%2C26%2C36%2C14%2C60100',
    },
    'basketball': {
        'sport_id':  'sr%3Asport%3A2',
        'market_ids': '219%2C18%2C223%2C1%2C14',
    },
    'tennis': {
        'sport_id':  'sr%3Asport%3A5',
        'market_ids': '186%2C189%2C202%2C188%2C18',
    },
}

# Market ID → display name
MARKET_NAMES = {
    '1':   '1X2',
    '18':  'Over/Under 2.5',
    '219': 'Home/Away',
    '186': 'Home/Away',
}

# Outcome ID → display name (SportyBet uses numeric IDs for 1X2)
OUTCOME_MAP = {
    '1': 'Home', '2': 'Draw', '3': 'Away',   # 1X2
    '4': 'Over', '5': 'Under',                # Over/Under
    '6': 'Home', '7': 'Away',                 # Moneyline (basketball/tennis)
}


class SportyBetScraper(BaseScraper):

    def __init__(self):
        super().__init__('SportyBet')
        # Replace headers entirely — Accept-Language causes 422 on this API
        self.session.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
            'Accept': 'application/json, text/plain, */*',
            'Referer': 'https://www.sportybet.com/ng/sport/football',
            'Origin':  'https://www.sportybet.com',
        }

    def get_events(self, sport: str) -> List[Event]:
        cfg = SPORT_CONFIG.get(sport)
        if not cfg:
            return []

        events: List[Event] = []
        try:
            data = self._fetch(cfg['sport_id'], cfg['market_ids'])
            tournaments = data.get('tournaments', [])
            for tournament in tournaments:
                league = tournament.get('name', '')
                for raw in tournament.get('events', []):
                    parsed = self._parse(raw, sport, league)
                    events.extend(parsed)
        except Exception as ex:
            logger.error(f"[SportyBet] {sport} fetch error: {ex}")

        return events

    def _fetch(self, sport_id: str, market_ids: str) -> dict:
        # Build URL manually — passing via params dict changes encoding and causes 422
        ts = int(time.time() * 1000)
        url = (
            f"{BASE_URL}"
            f"?sportId={sport_id}"
            f"&marketId={market_ids}"
            f"&pageSize=100&pageNum=1&option=1&_t={ts}"
        )
        resp = self.session.get(url, timeout=15)
        resp.raise_for_status()
        return resp.json().get('data', {})

    def _parse(self, raw: dict, sport: str, league: str = '') -> List[Event]:
        """Return one Event per market in the raw event."""
        home = raw.get('homeTeamName', '').strip()
        away = raw.get('awayTeamName', '').strip()
        if not home or not away:
            return []

        ts = raw.get('estimateStartTime', 0)
        starts_at = datetime.utcfromtimestamp(ts / 1000) if ts else None

        result: List[Event] = []
        for market in raw.get('markets', []):
            market_id = str(market.get('id', ''))
            market_name = MARKET_NAMES.get(market_id, market.get('name', market_id))

            # For Over/Under market, only keep the 2.5 line
            if market_id == '18':
                specifier = market.get('specifier', '')
                if 'total=2.5' not in specifier:
                    continue

            outcomes = []
            for o in market.get('outcomes', []):
                oid = str(o.get('id', ''))
                name = OUTCOME_MAP.get(oid, o.get('desc', oid))
                try:
                    odds = float(o.get('odds', 0))
                except (TypeError, ValueError):
                    continue
                if odds > 1.0:
                    outcomes.append(Outcome(name=name, odds=odds, bookmaker='SportyBet'))

            if len(outcomes) >= 2:
                result.append(Event(
                    event_id=f"sb_{raw.get('eventId', '')}_{market_id}",
                    bookmaker='SportyBet',
                    sport=sport,
                    home_team=home,
                    away_team=away,
                    market=market_name,
                    outcomes=outcomes,
                    starts_at=starts_at,
                    league=league,
                ))

        return result
