#!/usr/bin/env python3
"""
Natiris TUI – Text User Interface für den Companion
Features:
- Realtime State Anzeige
- Chat Interface (simuliert)
- Admin-Befehle
- Quick Actions
"""

import curses
import json
import os
import sys
import time
from datetime import datetime, timezone

PATHS = {
    "state": os.path.expanduser("~/natiris/core/natiris_full_state.json"),
    "config": os.path.expanduser("~/natiris/config/character_genesis.json"),
    "ollama": os.path.expanduser("~/natiris/bridges/ollama_response.json"),
    "log": os.path.expanduser("~/natiris/admin/admin_log.json"),
}

class NatirisTUI:
    def __init__(self, stdscr):
        self.stdscr = stdscr
        self.running = True
        self.mode = "STATE"  # STATE, CHAT, ADMIN
        self.user_input = ""
        self.log_lines = []
        self.last_update = 0
        self.state = {}
        self.response = ""

        # Init
        curses.curs_set(0)
        curses.start_color()
        curses.use_default_colors()
        curses.init_pair(1, curses.COLOR_CYAN, -1)
        curses.init_pair(2, curses.COLOR_GREEN, -1)
        curses.init_pair(3, curses.COLOR_YELLOW, -1)
        curses.init_pair(4, curses.COLOR_RED, -1)
        curses.init_pair(5, curses.COLOR_WHITE, -1)
        self.stdscr.nodelay(True)

        # Initial load
        self.update_state()

    def update_state(self):
        try:
            with open(PATHS["state"]) as f:
                self.state = json.load(f)
        except Exception:
            self.state = {}

        try:
            with open(PATHS["ollama"]) as f:
                resp = json.load(f)
                self.response = resp.get("response", "")[:120]
        except Exception:
            self.response = ""

        self.last_update = time.time()

    def draw_header(self):
        h, w = self.stdscr.getmaxyx()
        self.stdscr.attron(curses.color_pair(1) | curses.A_BOLD)
        self.stdscr.addstr(0, 2, " NATIRIS COMPANION v4.x ")
        self.stdscr.attroff(curses.color_pair(1) | curses.A_BOLD)
        self.stdscr.addstr(1, 2, f" Uptime: {int(time.time() - os.path.getmtime(PATHS['state']) if os.path.exists(PATHS['state']) else time.time())}s ")
        self.stdscr.addstr(2, 2, f" Mode: {self.mode} | {datetime.now(timezone.utc).strftime('%H:%M:%S')} ")

    def draw_state_panel(self, top, left, height, width):
        box_top = top
        box_left = left
        box_height = height
        box_width = width

        # Box frame
        self.stdscr.attron(curses.color_pair(5))
        for y in range(box_top, box_top + box_height):
            self.stdscr.addstr(y, box_left, "│")
            self.stdscr.addstr(y, box_left + box_width - 1, "│")
        self.stdscr.addstr(box_top, box_left, "┌")
        self.stdscr.addstr(box_top, box_left + box_width - 1, "┐")
        self.stdscr.addstr(box_top + box_height - 1, box_left, "└")
        self.stdscr.addstr(box_top + box_height - 1, box_left + box_width - 1, "┘")
        self.stdscr.addstr(box_top, box_left + 1, "─" * (box_width - 2))
        self.stdscr.addstr(box_top + box_height - 1, box_left + 1, "─" * (box_width - 2))
        self.stdscr.attroff(curses.color_pair(5))

        # Title
        self.stdscr.attron(curses.color_pair(2) | curses.A_BOLD)
        self.stdscr.addstr(box_top, box_left + 2, " CORE STATE ")
        self.stdscr.attroff(curses.color_pair(2) | curses.A_BOLD)

        state = self.state.get("modules", {})
        core = self.state.get("core_state", {})

        lines = [
            f" Mood: {core.get('mood', '?')}/10",
            f" Loneliness: {core.get('loneliness', '?')}/10",
            f" Anxiety: {core.get('anxiety', '?')}/10",
            f" Bonded: {core.get('bonded_to') or 'none'}",
            f" Exclusivity: {state.get('Bond', {}).get('exclusivity_active', False)}",
            f" Tone: {state.get('Expression', {}).get('tone', 'neutral')}",
            f" Response: {self.response}",
        ]

        for i, line in enumerate(lines):
            self.stdscr.addstr(box_top + 2 + i, box_left + 2, line[:box_width - 4])

    def draw_chat_panel(self, top, left, height, width):
        box_top = top
        box_left = left
        box_height = height
        box_width = width

        self.stdscr.attron(curses.color_pair(5))
        for y in range(box_top, box_top + box_height):
            self.stdscr.addstr(y, box_left, "│")
            self.stdscr.addstr(y, box_left + box_width - 1, "│")
        self.stdscr.addstr(box_top, box_left, "┌")
        self.stdscr.addstr(box_top, box_left + box_width - 1, "┐")
        self.stdscr.addstr(box_top + box_height - 1, box_left, "└")
        self.stdscr.addstr(box_top + box_height - 1, box_left + box_width - 1, "┘")
        self.stdscr.addstr(box_top, box_left + 1, "─" * (box_width - 2))
        self.stdscr.addstr(box_top + box_height - 1, box_left + 1, "─" * (box_width - 2))
        self.stdscr.attroff(curses.color_pair(5))

        self.stdscr.attron(curses.color_pair(3) | curses.A_BOLD)
        self.stdscr.addstr(box_top, box_left + 2, " CHAT OUTPUT ")
        self.stdscr.attroff(curses.color_pair(3) | curses.A_BOLD)

        if self.mode == "CHAT":
            self.stdscr.addstr(box_top + box_height - 1, box_left + 2, f"> {self.user_input}_")
        else:
            self.stdscr.addstr(box_top + box_height - 1, box_left + 2, " [Press 'c' for chat, 'a' for admin] ")

    def draw_admin_panel(self, top, left, height, width):
        box_top = top
        box_left = left
        box_height = height
        box_width = width

        self.stdscr.attron(curses.color_pair(5))
        for y in range(box_top, box_top + box_height):
            self.stdscr.addstr(y, box_left, "│")
            self.stdscr.addstr(y, box_left + box_width - 1, "│")
        self.stdscr.addstr(box_top, box_left, "┌")
        self.stdscr.addstr(box_top, box_left + box_width - 1, "┐")
        self.stdscr.addstr(box_top + box_height - 1, box_left, "└")
        self.stdscr.addstr(box_top + box_height - 1, box_left + box_width - 1, "┘")
        self.stdscr.addstr(box_top, box_left + 1, "─" * (box_width - 2))
        self.stdscr.addstr(box_top + box_height - 1, box_left + 1, "─" * (box_width - 2))
        self.stdscr.attroff(curses.color_pair(5))

        self.stdscr.attron(curses.color_pair(4) | curses.A_BOLD)
        self.stdscr.addstr(box_top, box_left + 2, " ADMIN ")
        self.stdscr.attroff(curses.color_pair(4) | curses.A_BOLD)

        help_lines = [
            " Commands:",
            "  s = status",
            "  e = emotion reset",
            "  m <val> = mood set",
            "  t <val> = trust set",
            "  r = bond reset",
            "  d = debug",
        ]

        for i, line in enumerate(help_lines):
            self.stdscr.addstr(box_top + 2 + i, box_left + 2, line[:box_width - 4])

    def handle_input(self):
        try:
            key = self.stdscr.getch()
            if key == -1:
                return

            if key == ord('q'):
                self.running = False
            elif key == ord('c'):
                self.mode = "CHAT"
            elif key == ord('a'):
                self.mode = "ADMIN"
            elif key == ord('s') and self.mode == "ADMIN":
                os.system("cd ~/natiris/admin && python3 AdminInterface.py status")
                self.update_state()
            elif key == ord('e') and self.mode == "ADMIN":
                os.system("cd ~/natiris/admin && python3 AdminInterface.py emotion reset")
                self.update_state()
            elif key == ord('r') and self.mode == "ADMIN":
                os.system("cd ~/natiris/admin && python3 AdminInterface.py bond reset")
                self.update_state()
            elif key == ord('t') and self.mode == "ADMIN":
                os.system("cd ~/natiris/admin && python3 AdminInterface.py trust set 7")
                self.update_state()
            elif key == ord('m') and self.mode == "ADMIN":
                os.system("cd ~/natiris/admin && python3 AdminInterface.py mood set 7.5")
                self.update_state()
            elif key == curses.KEY_BACKSPACE or key == 127 or key == 8:
                if self.mode == "CHAT" and self.user_input:
                    self.user_input = self.user_input[:-1]
            elif key >= 32 and key < 127:
                if self.mode == "CHAT":
                    self.user_input += chr(key)

        except Exception:
            pass

    def run(self):
        while self.running:
            try:
                # Update every 2s
                if time.time() - self.last_update > 2:
                    self.update_state()

                self.stdscr.clear()
                h, w = self.stdscr.getmaxyx()

                # Header
                self.draw_header()

                # Panels
                panel_height = (h - 4) // 2
                panel_width = w // 2 - 4

                self.draw_state_panel(4, 2, panel_height, w // 2)
                if self.mode == "ADMIN":
                    self.draw_admin_panel(4 + panel_height, 2, panel_height + 2, w // 2)
                    self.draw_chat_panel(4 + panel_height, w // 2 + 2, panel_height + 2, w // 2 - 2)
                else:
                    self.draw_chat_panel(4, w // 2 + 2, h - 6, w // 2 - 4)

                self.handle_input()
                self.stdscr.refresh()

            except KeyboardInterrupt:
                self.running = False

def main():
    try:
        curses.wrapper(NatirisTUI)
    except Exception as e:
        print(f"TUI error: {e}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    main()
