from dataclasses import dataclass, field
from typing import List, Optional
from datetime import datetime
import re


@dataclass
class Outcome:
    name: str        # "Home", "Draw", "Away"
    odds: float
    bookmaker: str
    event_url: Optional[str] = None
    event_id:  str = ''          # scraper event_id, e.g. "1x_12345_1X2"


@dataclass
class Event:
    event_id: str
    bookmaker: str
    sport: str
    home_team: str
    away_team: str
    market: str      # "1X2", "Home/Away", "Over/Under 2.5"
    outcomes: List[Outcome]
    starts_at: Optional[datetime]
    league: str = ''

    @property
    def match_key(self) -> str:
        """Normalized key for cross-bookmaker matching."""
        teams = sorted([self._norm(self.home_team), self._norm(self.away_team)])
        return f"{self.sport}:{teams[0]}:{teams[1]}"

    @staticmethod
    def _norm(name: str) -> str:
        name = name.lower()
        name = re.sub(r'[^a-z0-9 ]', '', name)
        # Strip standalone generic club suffixes/prefixes so "Chelsea FC" == "Chelsea"
        name = re.sub(r'\b(fc|cf|afc|sc|ac|bk|fk|sk|asc|ssc|ss|rcd|rc|as|us|sd|cd|ud|de|if|ik|gd|hfc|nfc|bc)\b', '', name)
        name = re.sub(r'\s+', ' ', name).strip()
        return name


@dataclass
class MiddleOpportunity:
    sport: str
    event_name: str
    league: str
    over_line: float
    under_line: float
    over_bm: str
    under_bm: str
    over_odds: float
    under_odds: float
    over_url: Optional[str]
    under_url: Optional[str]
    over_eid: str
    under_eid: str
    window: float       # under_line - over_line (goal gap)
    miss_pct: float     # % lost per ₦100 if middle misses (negative = guaranteed profit)
    hit_pct: float      # % profit per ₦100 if middle hits
    starts_at: Optional[datetime]
    found_at: datetime = field(default_factory=datetime.now)

    def to_dict(self) -> dict:
        over_stake  = 100 * self.under_odds / (self.over_odds + self.under_odds)
        under_stake = 100 * self.over_odds  / (self.over_odds + self.under_odds)
        return {
            'sport':       self.sport,
            'event_name':  self.event_name,
            'league':      self.league,
            'over_line':   self.over_line,
            'under_line':  self.under_line,
            'over_bm':     self.over_bm,
            'under_bm':    self.under_bm,
            'over_odds':   self.over_odds,
            'under_odds':  self.under_odds,
            'over_url':    self.over_url,
            'under_url':   self.under_url,
            'window':      self.window,
            'miss_pct':    round(self.miss_pct, 2),
            'hit_pct':     round(self.hit_pct, 2),
            'over_stake':  round(over_stake, 2),
            'under_stake': round(under_stake, 2),
            'starts_at':   self.starts_at.strftime('%Y-%m-%d %H:%M') if self.starts_at else '—',
            'found_at':    self.found_at.strftime('%Y-%m-%d %H:%M:%S'),
        }


@dataclass
class ArbOpportunity:
    sport: str
    event_name: str
    market: str
    outcomes: List[dict]   # [{bookmaker, outcome, odds, stake, potential_return}]
    arb_percentage: float
    profit_per_100: float
    starts_at: Optional[datetime]
    league: str = ''
    found_at: datetime = field(default_factory=datetime.now)

    def to_dict(self) -> dict:
        return {
            'sport': self.sport,
            'event_name': self.event_name,
            'league': self.league,
            'market': self.market,
            'outcomes': self.outcomes,
            'arb_percentage': round(self.arb_percentage, 2),
            'profit_per_100': round(self.profit_per_100, 2),
            'starts_at': self.starts_at.strftime('%Y-%m-%d %H:%M') if self.starts_at else '—',
            'found_at': self.found_at.strftime('%Y-%m-%d %H:%M:%S'),
        }
