name = "Yiyliyo Chat"
description = "Public chat platform in terminal"
ind = 2

import socketio
import requests
import random
import threading
import sys
from string import ascii_lowercase, digits

from yiyliyo.utils.logger import console, info, warn, error, debug, _log
from rich.prompt import Confirm, Prompt
from rich.table import Table


def run():
    torRunning = Confirm.ask("Is the tor daemon running?")
    if not torRunning:
        error("Chat", "To connect to yiyliyo chat servers the tor daemon must be running")
        return

    proxies = {
        'http': 'socks5h://127.0.0.1:9050',
        'https': 'socks5h://127.0.0.1:9050'
    }

    ONION_URL = "http://jlzyuhgotpn4teehttvguyj25i7uylfurn2j2lgqghksig6ub74ew5ad.onion"
    NAMESPACE = '/chat'

    http_session = requests.Session()
    http_session.proxies = proxies

    sio = socketio.Client(http_session=http_session, logger=False, engineio_logger=False)

    display_name = Prompt.ask("Display name")

    # shared state
    public_rooms = {}
    room_list_event = threading.Event()
    chosen_room = {"code": None}

    @sio.event
    def connect():
        console.print("[green]✅ Connected to chat server via Tor[/green]")

    @sio.event
    def disconnect():
        console.print("[red]❌ Disconnected[/red]")

    @sio.on('message', namespace=NAMESPACE)
    def message(data):
        sender = data.get('name', 'Server')
        msg = data.get('message', '')
        if msg:
            _log(sender, "light_pink3", "Chat", msg)


    @sio.on("room_list", namespace=NAMESPACE)
    def room_list(data):
        public_rooms.clear()
        public_rooms.update(data)
        room_list_event.set()

    try:
        with console.status("Connecting to the server", spinner="moon"):
            sio.connect(
                ONION_URL,
                namespaces=[NAMESPACE],
                wait_timeout=30
            )

        got = room_list_event.wait(timeout=10)
        if got and public_rooms:
            view_rooms = Confirm.ask("View public rooms?")
            if view_rooms:
                table = Table(title="Public rooms")
                table.add_column("Name")
                table.add_column("Code")
                table.add_column("Members")

                for code, info in public_rooms.items():
                    table.add_row(info['name'], code, str(info['members']))

                console.print(table)

        code = Prompt.ask("Enter room code (or type 'new' to create)")
        if code.lower() == "new":
            code = Prompt.ask(
                "New room code",
                default="".join(random.choices(ascii_lowercase + digits, k=6))
            )
        chosen_room["code"] = code
        sio.emit("join", {"room": code, "name": display_name}, namespace=NAMESPACE)

        print("Type your message and press Enter (or 'exit' to quit):")
        while True:
            msg = input("")
            if msg.lower() in ("exit", "quit"):
                break
            sys.stdout.write("\033[F\033[K")
            sys.stdout.flush()
            sio.emit('message', {"data": msg}, namespace=NAMESPACE)

    except socketio.exceptions.ConnectionError:
        error("🚨 Connection failed! Is the Tor service running and is your server correctly configured as an Onion Service?")
    except Exception as e:
        error(f"🚨 An unexpected error occurred: {e}")
    finally:
        if sio.connected:
            sio.disconnect()
