# core/live_updater.py
import threading
import streamlit as st
import time
from datetime import datetime
import numpy as np
from pathlib import Path   # ← THIS WAS MISSING — now added
import requests
from utils.event_discovery import discover_and_save_new_events
from utils.polymarket_fetch import fetch_new_prices, extract_yes_buckets, fetch_event
from utils.xtracker_fetch import fetch_xtracker_cached
from core.data_loader import load_surfaces

FLAG_FILE = Path(".life_updates.flag")


class LiveUpdater:
    def __init__(self, fast_interval_sec: int = 45, discovery_interval_sec: int = 3600):
        self.fast_interval = fast_interval_sec
        self.discovery_interval = discovery_interval_sec
        self.thread = None
        self.running = FLAG_FILE.exists()
        self.last_fast = 0
        self.last_discovery = 0
        # Thread-safe status (no Streamlit calls inside thread)
        self.status_fast = "⏸️ Not started"
        self.status_discovery = "⏸️ Not started"
        if self.running:
            self.thread = threading.Thread(target=self._background_loop, daemon=True)
            self.thread.start()


    def _background_loop(self):
        while self.running:
            try:
                now = time.time()
                # FAST CYCLE: prices + XTracker (every 45s)
                if now - self.last_fast >= self.fast_interval:
                    self.status_fast = "🔄 Updating prices + XTracker..."
                    self._update_existing(self.last_fast)
                    fetch_xtracker_cached()
                    self.last_fast = now
                    self.status_fast = f"✅ Prices updated {datetime.now().strftime('%H:%M:%S')}"

                # SLOW CYCLE: new event discovery (every hour)
                if now - self.last_discovery >= self.discovery_interval:
                    self.status_discovery = "🔍 Checking for new events..."
                    discover_and_save_new_events()
                    self.last_discovery = now
                    self.status_discovery = f"✅ Discovery done {datetime.now().strftime('%H:%M:%S')}"

            except Exception as e:
                self.status_fast = f"❌ Error: {str(e)[:80]}"

            time.sleep(15)
            self.running=FLAG_FILE.exists()

    def _update_existing(self, start):
        """Clean, working version that always saves tokens correctly"""
        data_dir = Path(str(Path.cwd()) + "/data")
        files = list(data_dir.iterdir())
        for f in files:
            if not f.name.endswith(".npz"):
                continue
            try:
                data = np.load(f, allow_pickle=True)
                matrix = data["matrix"]
                meta = {k: data[k] for k in data.files if k != "matrix"}
                slug = meta.get("event_slug") or f.stem.replace("elon_surface_", "").replace("_FULL", "")

                #print(f"[LIVE_UPDATER] Updating {slug}...")

                from utils.polymarket_fetch import fetch_event, extract_yes_buckets
                event = fetch_event(slug)
                if not event:
                    #print(f"[LIVE_UPDATER]   fetch_event failed for {slug}")
                    continue

                buckets = extract_yes_buckets(event)
                meta["tokens"] = [b.get("token") for b in buckets]
                meta["bins"]   = [b.get("label", str(b)) for b in buckets]

                # Save cleanly
                np.savez_compressed(f, matrix=matrix, **meta)
                #print(f"[LIVE_UPDATER]   ✅ Saved {len(meta['tokens'])} bins/tokens for {slug}")
            except Exception as e:
                print(f"[LIVE_UPDATER]   ❌ Error on {f.name}: {e}")

    def start(self):
        if self.running: return
        self.running = True
        self.thread = threading.Thread(target=self._background_loop, daemon=True)
        self.thread.start()

    def stop(self):
        self.running = False
        self.status_fast = "⏹️ Stopped"
        self.status_discovery = "⏹️ Stopped"
