"""
Sports Betting Bot - Late Entry Strategy
Based on ATSwins model for edge detection
"""

import os
import json
import time
from datetime import datetime

os.environ['KALSHI_API_KEY_ID'] = '81fe00fc-27b2-48ca-85f8-9c37ec1dc82f'
os.environ['KALSHI_PRIVATE_KEY_PATH'] = './kalshi_private_key'

from pykalshi import KalshiClient, MarketStatus

# Config
PAPER_BALANCE = 1500
TARGET = 0.15  # 15% profit target
STOP = 0.12    # 12% stop loss
POSITION = 0.10 # 10% per trade
MAX_OPEN = 3    # cap open positions
REV_THRESHOLD = 0.06  # 6c deviation from recent avg

class SportsBot:
    def __init__(self):
        self.client = None
        self.balance = PAPER_BALANCE
        self.positions = []
        self.trades = []
        self.prices = {}
        
    def setup(self):
        self.client = KalshiClient()
        print("✅ Sports Bot Connected")
        return self
    
    def get_sports_markets(self):
        """Get sports markets with spreads/totals for ATSwins leagues"""
        markets = self.client.get_markets(status=MarketStatus.OPEN, limit=500)

        leagues = [
            'nfl', 'nba', 'nhl', 'mlb', 'ncaab', 'ncaaf',
            'college basketball', 'college football'
        ]

        # Filter for spreads/totals with volume + league match
        sports = []
        for m in markets:
            if m.volume > 0:
                title = m.title.lower()
                if ('wins by' in title or 'over ' in title or 'under ' in title) and any(lg in title for lg in leagues):
                    sports.append(m)

        return sports
    
    def price(self, market):
        if market.yes_bid == 0 and market.yes_ask == 0:
            return 0
        return (market.yes_bid + market.yes_ask) / 200
    
    def run(self, cycles=20, delay=5):
        print(f"\n🏀 Sports Bot Running...")
        print(f"   Balance: ${PAPER_BALANCE}")
        print(f"   Target: +{TARGET*100:.0f}% | Stop: -{STOP*100:.0f}%")
        
        for i in range(cycles):
            markets = self.get_sports_markets()
            
            # Check exits
            self.check_exits(markets)
            
            # Check entries - mean reversion fade
            for m in markets:
                if any(p['status'] == 'open' and p['ticker'] == m.ticker for p in self.positions):
                    continue
                if len([p for p in self.positions if p['status'] == 'open']) >= MAX_OPEN:
                    continue

                curr = self.price(m)
                if curr == 0:
                    continue

                # Track price
                if m.ticker not in self.prices:
                    self.prices[m.ticker] = []
                self.prices[m.ticker].append(curr)
                if len(self.prices[m.ticker]) > 6:
                    self.prices[m.ticker] = self.prices[m.ticker][-6:]

                if len(self.prices[m.ticker]) < 4:
                    continue

                avg = sum(self.prices[m.ticker]) / len(self.prices[m.ticker])
                diff = curr - avg

                # Fade extremes: if price spikes above avg, bet NO; below avg, bet YES
                if diff >= REV_THRESHOLD:
                    self.enter(m, 'NO', curr)
                elif diff <= -REV_THRESHOLD:
                    self.enter(m, 'YES', curr)
            
            # Stats
            closed = [t for t in self.trades if t['status'] == 'closed']
            wins = len([t for t in closed if t.get('pnl', 0) > 0])
            open_pos = len([p for p in self.positions if p['status'] == 'open'])
            
            print(f"[{i+1}] Markets: {len(markets)} | Open: {open_pos} | Balance: ${self.balance:.0f}")
            
            time.sleep(delay)
        
        # Final
        self.print_stats()
        
        with open('sports_bot_results.json', 'w') as f:
            json.dump({
                'balance': self.balance,
                'trades': self.trades,
                'positions': self.positions
            }, f, indent=2, default=str)
    
    def enter(self, market, side, price):
        contracts = int(self.balance * POSITION)
        if contracts < 1:
            return
        
        pos = {
            'ticker': market.ticker,
            'title': market.title[:50],
            'side': side,
            'entry': price,
            'contracts': contracts,
            'time': datetime.now().isoformat(),
            'status': 'open'
        }
        
        self.positions.append(pos)
        self.balance -= contracts
        
        print(f"\n📝 ENTER {side} @ {price*100:.0f}¢")
        print(f"   {market.title[:40]}...")
    
    def check_exits(self, markets):
        market_dict = {m.ticker: m for m in markets}
        
        for p in self.positions:
            if p['status'] != 'open':
                continue
            if p['ticker'] not in market_dict:
                continue
            
            m = market_dict[p['ticker']]
            curr = self.price(m)
            
            if p['side'] == 'YES':
                pnl_pct = (curr - p['entry']) / p['entry'] if p['entry'] > 0 else 0
            else:
                pnl_pct = (p['entry'] - curr) / p['entry'] if p['entry'] > 0 else 0
            
            if pnl_pct >= TARGET:
                self.close(p, curr, "WIN")
            elif pnl_pct <= -STOP:
                self.close(p, curr, "STOP")
    
    def close(self, pos, price, reason):
        pnl = (price - pos['entry']) * pos['contracts'] if pos['side'] == 'YES' else (pos['entry'] - price) * pos['contracts']
        
        self.balance += pos['contracts'] + pnl
        pos['status'] = 'closed'
        pos['pnl'] = pnl
        pos['exit'] = price
        pos['reason'] = reason
        self.trades.append(pos)
        
        if pnl > 0:
            print(f"\n✅ {reason}: +${pnl:.0f}")
        else:
            print(f"\n❌ {reason}: ${pnl:.0f}")
    
    def print_stats(self):
        closed = [t for t in self.trades if t['status'] == 'closed']
        if closed:
            wins = [t for t in closed if t.get('pnl', 0) > 0]
            print(f"\n{'='*50}")
            print(f"FINAL: ${self.balance:.2f}")
            print(f"Trades: {len(closed)} | Wins: {len(wins)} | Win Rate: {len(wins)/len(closed)*100:.0f}%")

if __name__ == '__main__':
    SportsBot().setup().run(cycles=20, delay=5)
