import sys
import time
import threading
import json
from datetime import datetime, timezone
from loguru import logger

from gitchat.core import git, git_output, push_message

class Chat:
    def __init__(self, username: str, delay: float = 1.0, cwd = "."):
        self.username = username
        self.delay = delay
        self.cwd = cwd
        self.last_seen: dict[str, int] = {}
        self.stop_event = threading.Event()
        self.fetcher_thread = None

    def fetch_and_process(self):
        """Run git fetch and display new messages from other branches."""
        git("fetch", "origin", cwd=self.cwd, check=False)

        branches = git_output("branch", "-r", cwd=self.cwd)
        if not branches:
            return
        # Parse branch names (ex. origin/user)
        remote_branches = [b.strip() for b in branches.splitlines() if b.strip() and not b.strip().endswith("HEAD")]
        for full_branch in remote_branches:
            if not full_branch.startswith("origin/"):
                continue
            branch = full_branch.split("/", 1)[1]
            # Skip own branch
            if branch == self.username:
                continue

            messages = []
            try:
                content = git_output("show", f"{full_branch}:{branch}.json", cwd=self.cwd)
                if not content:
                    continue
                messages = json.loads(content)
            except Exception as e:
                logger.error(f"Failed to read new messages: {e}")
                continue

            # Determine new messages
            now = datetime.now(timezone.utc).timestamp()
            seen = self.last_seen.get(branch, 0)
            if len(messages) > seen:
                for i in range(seen, len(messages)):
                    # Message must be created not later than 2 mins ago
                    if now - messages[i]["timestamp"] < 120:
                        logger.info(f"[{branch}] {messages[i]['data']}")
                self.last_seen[branch] = len(messages)

    def fetcher_loop(self):
        """Periodically fetches and prints messages"""
        while not self.stop_event.is_set():
            self.fetch_and_process()
            time.sleep(self.delay)

    def send_loop(self):
        """Read stdin and send messages"""
        logger.debug(f"Chat started as `{self.username}`. Type messages and press Enter. Ctrl+C to exit.")
        while not self.stop_event.is_set():
            try:
                line = sys.stdin.readline()
                if not line:
                    break
                text = line.strip()
                if text:
                    push_message(self.username, text, cwd=self.cwd)
            except Exception as e:
                logger.error(f"Error sending message: {e}")

    def start(self):
        """Entrypoint for chat"""
        self.fetcher_thread = threading.Thread(target=self.fetcher_loop, daemon=True)
        self.fetcher_thread.start()
        try:
            self.send_loop()
        except KeyboardInterrupt:
            print("\nExiting...")
        finally:
            self.stop_event.set()
            if self.fetcher_thread.is_alive():
                self.fetcher_thread.join(timeout=2)
