# app/src/telegram/handlers/debug_auto/main.py

from __future__ import annotations

import time

from aiogram import F, Router
from aiogram.exceptions import TelegramBadRequest
from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery, Message

from src.telegram.handlers.debug_auto.ui import (
    build_debug_auto_text,
    debug_auto_keyboard,
)
from src.telegram.live.active_screen import ActiveScreenManager
from src.trading.debug.runner import DebugTradeRunner
from src.trading.debug.service import DebugTradeService


router = Router(name="debug_auto")


def _ensure_signal_started_at(state) -> None:
    if state.signal_started_at is None:
        state.signal_started_at = time.monotonic()


async def render_debug_auto_screen(
    target_message: Message,
    *,
    edit_mode: bool,
) -> None:
    text = build_debug_auto_text()

    if edit_mode:
        try:
            await target_message.edit_text(
                text,
                reply_markup=debug_auto_keyboard(),
            )
        except TelegramBadRequest as exc:
            if "message is not modified" not in str(exc).lower():
                raise

        DebugTradeRunner.register_screen(
            bot=target_message.bot,
            chat_id=target_message.chat.id,
            message_id=target_message.message_id,
            render_text=build_debug_auto_text,
            render_markup=debug_auto_keyboard,
        )

        ActiveScreenManager.register(
            screen="debug_auto",
            message=target_message,
        )
        return

    sent_message = await target_message.answer(
        text,
        reply_markup=debug_auto_keyboard(),
    )

    DebugTradeRunner.register_screen(
        bot=sent_message.bot,
        chat_id=sent_message.chat.id,
        message_id=sent_message.message_id,
        render_text=build_debug_auto_text,
        render_markup=debug_auto_keyboard,
    )

    ActiveScreenManager.register(
        screen="debug_auto",
        message=sent_message,
    )


async def _prepare_debug_auto_from_message(message: Message) -> None:
    await ActiveScreenManager.prepare_new_screen(
        screen="debug_auto",
        bot=message.bot,
        chat_id=message.chat.id,
    )


async def _prepare_debug_auto_from_callback(callback: CallbackQuery) -> bool:
    if callback.message is None:
        await callback.answer("Сообщение не найдено", show_alert=True)
        return False

    await ActiveScreenManager.prepare_new_screen(
        screen="debug_auto",
        bot=callback.message.bot,
        chat_id=callback.message.chat.id,
        keep_message_id=callback.message.message_id,
    )

    return True


@router.message(F.text.in_({"🧪 Debug Auto", "Debug Auto", "/debug_auto_screen"}))
async def open_debug_auto(message: Message, state: FSMContext) -> None:
    await state.clear()

    await _prepare_debug_auto_from_message(message)

    DebugTradeRunner.set_current_screen("debug_auto")

    await render_debug_auto_screen(message, edit_mode=False)


@router.callback_query(F.data == "debug_auto:start")
async def debug_auto_start(callback: CallbackQuery) -> None:
    service = DebugTradeService()
    state = service.get_state()
    state.status = "RUNNING"
    _ensure_signal_started_at(state)

    DebugTradeRunner.set_current_screen("debug_auto")
    DebugTradeRunner.start()

    if callback.message is not None:
        await _prepare_debug_auto_from_callback(callback)
        await render_debug_auto_screen(callback.message, edit_mode=True)

    await callback.answer("[DEBUG] Мониторинг запущен.")


@router.callback_query(F.data == "debug_auto:stop")
async def debug_auto_stop(callback: CallbackQuery) -> None:
    DebugTradeRunner.set_current_screen("debug_auto")
    DebugTradeRunner.stop()
    DebugTradeService().stop()

    if callback.message is not None:
        await _prepare_debug_auto_from_callback(callback)
        await render_debug_auto_screen(callback.message, edit_mode=True)

    await callback.answer("[DEBUG] Мониторинг остановлен.")


@router.callback_query(F.data == "debug_auto:long")
async def debug_auto_long(callback: CallbackQuery) -> None:
    service = DebugTradeService()
    _, result = service.open_long()

    DebugTradeRunner.set_current_screen("debug_auto")
    DebugTradeRunner.start()

    if callback.message is not None:
        await _prepare_debug_auto_from_callback(callback)
        await render_debug_auto_screen(callback.message, edit_mode=True)

    await callback.answer(result.reason, show_alert=False)


@router.callback_query(F.data == "debug_auto:short")
async def debug_auto_short(callback: CallbackQuery) -> None:
    service = DebugTradeService()
    _, result = service.open_short()

    DebugTradeRunner.set_current_screen("debug_auto")
    DebugTradeRunner.start()

    if callback.message is not None:
        await _prepare_debug_auto_from_callback(callback)
        await render_debug_auto_screen(callback.message, edit_mode=True)

    await callback.answer(result.reason, show_alert=False)


@router.callback_query(F.data == "debug_auto:flip")
async def debug_auto_flip(callback: CallbackQuery) -> None:
    service = DebugTradeService()
    _, result = service.flip()

    DebugTradeRunner.set_current_screen("debug_auto")
    DebugTradeRunner.start()

    if callback.message is not None:
        await _prepare_debug_auto_from_callback(callback)
        await render_debug_auto_screen(callback.message, edit_mode=True)

    await callback.answer(result.reason, show_alert=False)


@router.callback_query(F.data == "debug_auto:close")
async def debug_auto_close(callback: CallbackQuery) -> None:
    service = DebugTradeService()
    _, result = service.close(reason="DEBUG_SCREEN_CLOSE")

    DebugTradeRunner.set_current_screen("debug_auto")

    if callback.message is not None:
        await _prepare_debug_auto_from_callback(callback)
        await render_debug_auto_screen(callback.message, edit_mode=True)

    await callback.answer(result.reason, show_alert=False)


@router.callback_query(F.data == "debug_auto:reset")
async def debug_auto_reset(callback: CallbackQuery) -> None:
    DebugTradeRunner.set_current_screen("debug_auto")
    state = DebugTradeService().reset()
    _ensure_signal_started_at(state)

    if callback.message is not None:
        await _prepare_debug_auto_from_callback(callback)
        await render_debug_auto_screen(callback.message, edit_mode=True)

    await callback.answer("[DEBUG] Runtime reset.")