"""
MSport Nigeria scraper.

API endpoints and required headers discovered via Playwright network interception.
Key headers: operid=2, clientid=WEB, apilevel=2, platform=WEB
"""
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.msport.com/api/ng/facts-center/query/frontend"

SPORT_IDS = {
    'football':   'sr:sport:1',
    'basketball': 'sr:sport:2',
    'tennis':     'sr:sport:5',
}

# Market IDs we care about for arb
ARBI_MARKETS = {
    'football':   {1: '1X2', 14: 'Over/Under 2.5'},
    'basketball': {219: 'Home/Away', 1: '1X2'},
    'tennis':     {186: 'Home/Away'},  # market ID 186 = Winner on tennis
}

# MSport outcome ID → name  (same pattern as SportyBet)
OUTCOME_MAP = {
    '1': 'Home', '2': 'Draw', '3': 'Away',
    '4': 'Over', '5': 'Under',
}


class MSportScraper(BaseScraper):

    def __init__(self):
        super().__init__('MSport')
        # Replace session headers with exact set that works
        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.msport.com/ng/web',
            'clientid': 'WEB',
            'operid':   '2',
            'apilevel': '2',
            'platform': 'WEB',
        }

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

        events: List[Event] = []
        page = 1

        while True:
            try:
                raw_events, has_more = self._fetch_page(sport_id, page)
                for raw in raw_events:
                    events.extend(self._parse(raw, sport))
                if not has_more or page >= 10:   # cap at 1000 events
                    break
                page += 1
            except Exception as ex:
                logger.error(f"[MSport] {sport} page {page} error: {ex}")
                break

        return events

    def _fetch_page(self, sport_id: str, page: int):
        url = f"{BASE_URL}/all-matches/next-7-days"
        params = {
            'sportId':  sport_id,
            'pageSize': 100,
            'pageNum':  page,
        }
        resp = self.session.get(url, params=params, timeout=15)
        resp.raise_for_status()
        data = resp.json().get('data', {})
        raw_events = data.get('events', [])
        # has_more: if we got a full page, there might be more
        has_more = len(raw_events) == 100
        return raw_events, has_more

    def _parse(self, raw: dict, sport: str) -> List[Event]:
        home = (raw.get('homeTeam') or '').strip()
        away = (raw.get('awayTeam') or '').strip()
        if not home or not away:
            return []

        league = (raw.get('tournament') or '').strip()
        ts = raw.get('startTime') or raw.get('estimateStartTime')
        try:
            starts_at = datetime.utcfromtimestamp(ts / 1000) if ts else None
        except Exception:
            starts_at = None

        arb_market_ids = ARBI_MARKETS.get(sport, {})
        result: List[Event] = []

        for market in raw.get('markets', []):
            market_id = market.get('id')
            if market_id not in arb_market_ids:
                continue

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

            market_name = arb_market_ids[market_id]
            outcomes = []
            for o in market.get('outcomes', []):
                if not o.get('isActive', 1):
                    continue
                oid = str(o.get('id', ''))
                desc = o.get('description', oid)
                # For tennis Winner market, description is the player name; use Home/Away by position
                if sport == 'tennis' and market_id == 186:
                    name = 'Home' if oid == '1' else 'Away'
                else:
                    name = OUTCOME_MAP.get(oid, desc)
                try:
                    odds = float(o.get('odds', 0))
                except (TypeError, ValueError):
                    continue
                if odds > 1.0:
                    outcomes.append(Outcome(name=name, odds=odds, bookmaker='MSport'))

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

        return result
