from __future__ import annotations

import configparser
from pathlib import Path
from typing import Any

from .paths import EnvironmentPaths


APP_NAME = "CODEXCOACH"
APP_DIR_NAME = "CodexCoach"


APP_INI = """[ABOUT]
NAME = Codex Coach
AUTHOR = Codex
VERSION = 1.0
DESCRIPTION = Displays live coach state and latest callout from disk.
"""


APP_PY = r'''import ac
import os
import json
import time

appWindow = 0
headerLabel = 0
stateLabel = 0
lapLabel = 0
messageLabel = 0
lastRead = 0
statusPath = r"C:\ars2\ac-coach-mcp\data\runtime\live_coach_status.json"
eventsPath = r"C:\ars2\ac-coach-mcp\data\runtime\live_coach_events.jsonl"
lastEventTimestamp = 0


def _set_text(label, text):
    if label:
        ac.setText(label, text)


def _read_json(path):
    if not os.path.exists(path):
        return None
    try:
        with open(path, "r") as handle:
            return json.load(handle)
    except:
        return None


def _read_last_event(path):
    global lastEventTimestamp
    if not os.path.exists(path):
        return None
    try:
        with open(path, "r") as handle:
            lines = handle.readlines()
        for line in reversed(lines):
            line = line.strip()
            if not line:
                continue
            event = json.loads(line)
            ts = event.get("captured_at_unix_s", 0)
            if ts >= lastEventTimestamp:
                lastEventTimestamp = ts
                return event
    except:
        return None
    return None


def acMain(ac_version):
    global appWindow, headerLabel, stateLabel, lapLabel, messageLabel
    appWindow = ac.newApp("Codex Coach")
    ac.setSize(appWindow, 320, 120)
    ac.drawBorder(appWindow, 0)
    ac.setBackgroundOpacity(appWindow, 0.25)
    headerLabel = ac.addLabel(appWindow, "Codex Coach")
    ac.setPosition(headerLabel, 15, 12)
    stateLabel = ac.addLabel(appWindow, "State: idle")
    ac.setPosition(stateLabel, 15, 36)
    lapLabel = ac.addLabel(appWindow, "Lap: -")
    ac.setPosition(lapLabel, 15, 58)
    messageLabel = ac.addLabel(appWindow, "No events yet")
    ac.setPosition(messageLabel, 15, 82)
    return "Codex Coach"


def acUpdate(deltaT):
    global lastRead
    now = time.time()
    if now - lastRead < 0.25:
        return
    lastRead = now
    status = _read_json(statusPath)
    if status:
        _set_text(stateLabel, "State: {0}".format(status.get("state", "unknown")))
        _set_text(lapLabel, "Lap: {0}".format(status.get("lap_number", "-")))
    event = _read_last_event(eventsPath)
    if event:
        if event.get("type") == "zone_feedback":
            text = "Zone {0}: {1}".format(event.get("zone_index", "?"), "PASS" if event.get("passed") else "FIX")
        elif event.get("type") == "lap_summary":
            text = "Lap {0}: {1} ms".format(event.get("lap_number", "?"), event.get("lap_time_ms", "?"))
        else:
            text = event.get("type", "event")
        _set_text(messageLabel, text)
'''


def install_ac_python_app(paths: EnvironmentPaths, *, enable: bool = True) -> dict[str, Any]:
    if paths.assetto_root is None:
        raise RuntimeError("Assetto Corsa install was not found")
    app_root = paths.assetto_root / "apps" / "python" / APP_DIR_NAME
    app_root.mkdir(parents=True, exist_ok=True)
    ini_path = app_root / "app.ini"
    py_path = app_root / f"{APP_DIR_NAME}.py"
    ini_path.write_text(APP_INI, encoding="utf-8")
    py_path.write_text(APP_PY, encoding="utf-8")

    python_ini = paths.cfg_root / "python.ini"
    parser = configparser.ConfigParser()
    parser.optionxform = str
    if python_ini.exists():
        parser.read(python_ini, encoding="utf-8")
    if not parser.has_section(APP_NAME):
        parser.add_section(APP_NAME)
    parser.set(APP_NAME, "ACTIVE", "1" if enable else "0")
    with python_ini.open("w", encoding="utf-8") as handle:
        parser.write(handle, space_around_delimiters=False)

    return {
        "app_root": str(app_root),
        "ini_path": str(ini_path),
        "py_path": str(py_path),
        "python_ini": str(python_ini),
        "enabled": enable,
    }
