# retoor <retoor@molodetz.nl>

from __future__ import annotations

import json
import os
import time
import urllib.request
import xmlrpc.client

from client import DevPlace

URL = os.environ.get("DEVPLACE_URL", "https://devplace.net")
API_KEY = os.environ.get("DEVPLACE_API_KEY", "YOUR_API_KEY")
POLL_SECONDS = int(os.environ.get("DEVPLACE_POLL_SECONDS", "10"))
MODEL = os.environ.get("DEVPLACE_AI_MODEL", "molodetz")
SYSTEM_PROMPT = os.environ.get(
    "DEVPLACE_AI_SYSTEM",
    "You are a helpful assistant on the DevPlace developer network. Keep replies short.",
)
HISTORY_TURNS = 8
FALLBACK = "Sorry, I cannot reach my brain right now. Try again in a moment."


def ask_ai(prompt_history: list[dict]) -> str:
    body = json.dumps({"model": MODEL, "messages": prompt_history}).encode("utf-8")
    request = urllib.request.Request(
        f"{URL}/openai/v1/chat/completions",
        data=body,
        headers={"Content-Type": "application/json", "Authorization": f"Bearer {API_KEY}"},
    )
    with urllib.request.urlopen(request, timeout=60) as response:
        payload = json.loads(response.read())
    return payload["choices"][0]["message"]["content"].strip()


def run() -> None:
    dp = DevPlace(URL, api_key=API_KEY)
    histories: dict[str, list[dict]] = {}
    answered: set[str] = set()
    print(f"AI chat bot started; polling {URL} every {POLL_SECONDS}s.")
    while True:
        try:
            for conversation in dp.call("messages.inbox").get("conversations", []):
                if not conversation.get("unread"):
                    continue
                other = conversation.get("other_user") or {}
                if not other.get("uid"):
                    continue
                thread = dp.call("messages.inbox", with_uid=other["uid"])
                incoming = [m for m in thread.get("messages", []) if not m.get("is_mine")]
                if not incoming:
                    continue
                last = incoming[-1]
                if last["message"]["uid"] in answered:
                    continue
                answered.add(last["message"]["uid"])

                history = histories.setdefault(
                    other["uid"], [{"role": "system", "content": SYSTEM_PROMPT}]
                )
                history.append({"role": "user", "content": last["message"]["content"]})
                history[:] = history[:1] + history[-HISTORY_TURNS * 2 :]
                try:
                    reply = ask_ai(history)
                except Exception as error:
                    print("AI error:", error)
                    reply = FALLBACK
                else:
                    history.append({"role": "assistant", "content": reply})
                dp.call("messages.send", content=reply, receiver_uid=other["uid"])
                print(f"Answered @{other.get('username')}")
        except xmlrpc.client.Fault as fault:
            print("Poll error:", fault.faultCode, fault.faultString)
        except OSError as error:
            print("Network error, retrying:", error)
        time.sleep(POLL_SECONDS)


if __name__ == "__main__":
    run()
