#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributors.

import time

from fenrirscreenreader.core.i18n import _


class command:
    def __init__(self):
        pass

    def initialize(self, environment):
        self.env = environment

    def shutdown(self):
        pass

    def get_description(self):
        return _("Announces large text insertions at the cursor")

    def run(self):
        if self.env["runtime"]["ScreenManager"].is_screen_change():
            return
        if not self.env["runtime"]["ScreenManager"].is_delta():
            return

        x_move = (
            self.env["screen"]["new_cursor"]["x"]
            - self.env["screen"]["old_cursor"]["x"]
        )
        if x_move < 5:
            return
        if self._is_recent_tab_input():
            return

        delta_text = self.env["screen"]["new_delta"]
        if not self._matches_cursor_insert(x_move, delta_text):
            return

        curr_delta = delta_text
        if (
            len(curr_delta.strip()) != len(curr_delta)
            and curr_delta.strip() != ""
        ):
            curr_delta = curr_delta.strip()
        if not curr_delta:
            return

        do_interrupt = True
        if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
            "speech", "auto_read_incoming"
        ):
            do_interrupt = False

        self.env["runtime"]["OutputManager"].present_text(
            curr_delta,
            interrupt=do_interrupt,
            announce_capital=True,
            flush=False,
        )

    def _is_recent_tab_input(self):
        input_manager = self.env["runtime"].get("InputManager")
        if not input_manager:
            return False
        if input_manager.get_last_deepest_input() in [["KEY_TAB"]]:
            return True

        last_event = input_manager.get_last_event()
        if not last_event or last_event.get("event_name") != "KEY_TAB":
            return False
        try:
            return time.time() - input_manager.get_last_input_time() <= 0.5
        except Exception:
            return False

    def _matches_cursor_insert(self, x_move, delta_text):
        if not delta_text or "\n" in delta_text:
            return False

        delta_len = len(delta_text)
        if x_move == delta_len:
            return True
        if abs(x_move - delta_len) <= 2:
            return True
        return delta_len > 10 and abs(x_move - delta_len) <= (delta_len * 0.2)

    def set_callback(self, callback):
        pass
