"""Live-Zustand fuer Dashboard und Overlay.

Liest die Statusdateien des Bot-Loops (state/session/events) — entkoppelt
und ohne in die Thread-Interna zu fassen. Alles tolerant gegenueber
fehlenden oder halb geschriebenen Dateien.
"""
import json
import time
from pathlib import Path

STATE_FILE = Path('.pilotng-state.json')
SESSION_FILE = Path('.pilotng-session.json')
EVENTS_FILE = Path('.pilotng-events.jsonl')
OVERLAY_FILE = Path('.pilotng-overlay.json')
STATS_FILE = Path('.pilotng-stats.json')
HEATMAP_FILE = Path('.pilotng-heatmap.json')


def readJson(path):
    try:
        return json.loads(Path(path).read_text(encoding='utf-8'))
    except (OSError, ValueError):
        return None


def readState(path=STATE_FILE):
    return readJson(path) or {}


def readEvents(path=EVENTS_FILE, limit=5):
    try:
        lines = Path(path).read_text(encoding='utf-8').strip().split('\n')
    except OSError:
        return []
    events = []
    for line in reversed(lines[-limit:]):
        try:
            events.append(json.loads(line))
        except ValueError:
            continue
    return events


def readStats(path=STATS_FILE):
    return readJson(path) or {}


def readAllEvents(path=EVENTS_FILE):
    """Alle Events des Logs (rotiert bei ~1 MB) — fuer die Session-Bilanz."""
    try:
        lines = Path(path).read_text(encoding='utf-8').strip().split('\n')
    except OSError:
        return []
    events = []
    for line in lines:
        try:
            events.append(json.loads(line))
        except ValueError:
            continue
    return events


def sessionReport(now=None, stats_path=STATS_FILE, session_path=SESSION_FILE,
                  events_path=EVENTS_FILE):
    """Bilanz fuer den "Ich bin zurueck"-Button: Zeit, Loot, Vorfaelle.

    Zaehlt die Events seit Session-Start (Fenster aus der Stats-Datei).
    Gold/Exp/Level werden bewusst nicht geschaetzt — nur was der Bot
    wirklich protokolliert hat.
    """
    now = time.time() if now is None else now
    stats = readStats(stats_path)
    session = sessionSummary(session_path, now=now)
    since = now - stats.get('minutes', 0) * 60 if stats else 0
    events = []
    for event in readAllEvents(events_path):
        try:
            at = time.mktime(time.strptime(
                event.get('at', ''), '%Y-%m-%dT%H:%M:%S'))
        except (ValueError, OverflowError):
            continue
        if at >= since:
            events.append(event)
    counts = {}
    for event in events:
        kind = event.get('type', '?')
        counts[kind] = counts.get(kind, 0) + 1
    return {
        'playedSeconds': session['playedSeconds'],
        'stats': stats,
        'counts': counts,
        'events': events[-40:],
    }


def readHeatmap(path=HEATMAP_FILE):
    return readJson(path) or {'points': [], 'stucks': [], 'jumps': []}


def sessionSummary(path=SESSION_FILE, now=None):
    """Gespielte Zeit heute plus verbleibende Pause (falls aktiv)."""
    state = readJson(path)
    if not state:
        return {'playedSeconds': 0, 'breakRemainingSeconds': 0}
    now = time.time() if now is None else now
    return {
        'playedSeconds': state.get('playedSeconds', 0),
        'breakRemainingSeconds': max(state.get('breakUntil', 0) - now, 0),
    }


def formatDuration(seconds):
    seconds = int(seconds)
    hours, rest = divmod(seconds, 3600)
    minutes = rest // 60
    if hours:
        return f'{hours} h {minutes:02d} min'
    return f'{minutes} min'


def loadOverlayPosition(path=OVERLAY_FILE, margin=24):
    data = readJson(path)
    if (isinstance(data, dict) and
            isinstance(data.get('x'), int) and isinstance(data.get('y'), int)):
        return max(data['x'], 0), max(data['y'], 0)
    return None


def saveOverlayPosition(x, y, path=OVERLAY_FILE):
    try:
        Path(path).write_text(
            json.dumps({'x': int(x), 'y': int(y)}), encoding='utf-8',
        )
    except OSError:
        pass
