#!/usr/bin/env python3
"""Telegram notification and command handler for Mentions Market Maker"""

import os
import requests
import threading
import time
import concurrent.futures
from typing import Optional

_tg_pool = concurrent.futures.ThreadPoolExecutor(max_workers=2, thread_name_prefix="tg")


class TelegramNotifier:
    """Handle Telegram notifications and commands for mentions maker"""

    def __init__(self, bot_token: str, chat_id: str, trader=None):
        self.bot_token = bot_token
        self.chat_id = chat_id
        self.trader = trader
        self.base_url = f"https://api.telegram.org/bot{bot_token}"
        self.last_update_id = 0
        self.running = False

    def _do_send(self, text: str) -> bool:
        try:
            response = requests.post(
                f"{self.base_url}/sendMessage",
                json={
                    "chat_id": self.chat_id,
                    "text": text,
                    "parse_mode": "HTML",
                },
                timeout=5,
            )
            return response.status_code == 200
        except Exception:
            return False

    def send(self, text: str):
        _tg_pool.submit(self._do_send, text)

    def notify_startup(self, market_id: str, contract_increment: int, one_side_first: bool, active_side: str = None):
        mode = f"ONE-SIDE-FIRST ({active_side.upper()} first)" if one_side_first else "BOTH SIDES"
        self.send(
            f"🟢 <b>Mentions Maker Started</b>\n"
            f"Market: <code>{market_id}</code>\n"
            f"Mode: {mode}\n"
            f"Contracts: {contract_increment}"
        )

    def notify_cycle_complete(self, yes_pos: int, no_pos: int, increment: int):
        self.send(
            f"✅ <b>Cycle Complete</b>\n"
            f"Filled {increment} each side\n"
            f"Position: YES={yes_pos}, NO={no_pos}"
        )

    def notify_fill(self, side: str, price: float, count: int, yes_pos: int, no_pos: int):
        self.send(
            f"💰 <b>Fill: {count} {side.upper()} @ ${price:.2f}</b>\n"
            f"Position: YES={yes_pos}, NO={no_pos}"
        )

    def notify_rebalance(self, side: str, count: int, price: float):
        self.send(
            f"⚖️ <b>Rebalancing</b>\n"
            f"Buying {count} {side.upper()} @ ${price:.2f}"
        )

    def notify_error(self, msg: str):
        self.send(f"❌ {msg}")

    def notify_stopped(self):
        self.send("🔴 <b>Mentions Maker Stopped</b>")

    def notify_paused(self):
        self.send("⏸️ Paused")

    def notify_resumed(self):
        self.send("▶️ Resumed")

    def notify_status(self, trader):
        yes_bid = f"${trader.market_state.yes_bid:.2f}" if trader.market_state.yes_bid else "N/A"
        no_bid = f"${trader.market_state.no_bid:.2f}" if trader.market_state.no_bid else "N/A"
        yes_pos = trader.cached_position.get("yes") or 0
        no_pos = trader.cached_position.get("no") or 0
        spread = trader.get_market_spread()
        spread_str = f"{spread}c" if spread is not None else "N/A"
        mode = "PAUSED" if trader.paused else "ACTIVE"
        side_str = f" [{trader.active_side.upper()}]" if trader.one_side_first_mode else ""

        self.send(
            f"📊 <b>Status{side_str} ({mode})</b>\n"
            f"Market: <code>{trader.market_id}</code>\n"
            f"YES bid: {yes_bid} | NO bid: {no_bid}\n"
            f"Spread: {spread_str}\n"
            f"Cycle: YES {trader.current_increment['yes']}/{trader.contract_increment}, "
            f"NO {trader.current_increment['no']}/{trader.contract_increment}\n"
            f"Position: YES={yes_pos}, NO={no_pos}"
        )

    def start_listener(self):
        self.running = True
        t = threading.Thread(target=self._poll_commands, daemon=True)
        t.start()

    def _poll_commands(self):
        while self.running:
            try:
                resp = requests.get(
                    f"{self.base_url}/getUpdates",
                    params={"offset": self.last_update_id + 1, "timeout": 10},
                    timeout=15,
                )
                if resp.status_code == 200:
                    for update in resp.json().get("result", []):
                        self.last_update_id = update["update_id"]
                        msg = update.get("message", {})
                        text = msg.get("text", "").strip().lower()
                        if text.startswith("/"):
                            self._handle_command(text)
            except Exception:
                time.sleep(5)

    def _handle_command(self, cmd: str):
        if not self.trader:
            return

        if cmd == "/p":
            if self.trader.paused:
                self.trader.paused = False
                self.trader.waiting_for_manual_resume = False
                self.notify_resumed()
            else:
                self.trader.paused = True
                self.notify_paused()

        elif cmd == "/status":
            self.notify_status(self.trader)

        elif cmd == "/f":
            # Single fire
            if self.trader.active and (self.trader.paused or self.trader.waiting_for_manual_resume):
                self.trader.single_fire_mode = True
                self.trader.single_fire_sides_completed = 0
                self.trader.paused = False
                self.send("🎯 Single fire mode")
            else:
                self.send("⚠️ Must be paused to single fire")

        elif cmd == "/z":
            self.trader.emergency_stop = True
            self.send("⛔ Emergency stop requested")

        elif cmd == "/s":
            self.trader.stopping = True
            self.send("⏳ Stopping after current cycle...")

        elif cmd.startswith("/c "):
            try:
                new_size = int(cmd.split()[1])
                if 1 <= new_size <= 50:
                    self.trader.contract_increment = new_size
                    self.send(f"✓ Contract size: {new_size}")
                else:
                    self.send("❌ Size must be 1-50")
            except (ValueError, IndexError):
                self.send("❌ Usage: /c [size]")
