#!/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 _("Handles delayed retry for tab completion detection")

    def run(self):
        """Check for and process pending tab completions with slight delay"""
        # Only process if we have tab completion state
        if "tabCompletion" not in self.env["commandBuffer"]:
            return

        tab_state = self.env["commandBuffer"]["tabCompletion"]
        pending = tab_state.get("pendingCompletion")
        
        if not pending:
            return

        current_time = time.time()
        
        # Process pending completion after 50ms delay
        if current_time - pending["timestamp"] < 0.05:
            return

        # Check if screen delta is now available
        if not self.env["runtime"]["ScreenManager"].is_delta():
            # Give up after 200ms total
            if current_time - pending["timestamp"] > 0.2:
                tab_state["pendingCompletion"] = None
                tab_state["retryCount"] = 0
            return

        # Process the delayed completion
        delta_text = self.env["screen"]["new_delta"]
        x_move = pending["x_move"]
        
        # Use the same flexible matching logic as main tab completion
        match_found = self._is_flexible_completion_match(x_move, delta_text)
        
        if not match_found:
            # Try pattern-based detection as final fallback
            match_found = self._detect_completion_patterns(delta_text)

        if match_found and delta_text:
            # Mark that we've handled this delta to prevent duplicate announcements
            tab_state["lastProcessedDelta"] = delta_text
            tab_state["lastProcessedTime"] = current_time
            
            # Filter and announce the completion
            curr_delta = delta_text
            if (len(curr_delta.strip()) != len(curr_delta) and 
                curr_delta.strip() != ""):
                curr_delta = curr_delta.strip()
            
            if curr_delta:
                self.env["runtime"]["OutputManager"].present_text(
                    curr_delta, interrupt=True, announce_capital=True, flush=False
                )

        # Clear pending completion
        tab_state["pendingCompletion"] = None
        tab_state["retryCount"] = 0

    def _is_flexible_completion_match(self, x_move, delta_text):
        """Use flexible matching (duplicated from main command for heartbeat use)"""
        if not delta_text:
            return False
        
        delta_len = len(delta_text)
        
        # Exact match
        if x_move == delta_len:
            return True
        
        # Flexible range: allow ±2 characters difference
        if abs(x_move - delta_len) <= 2 and delta_len > 0:
            return True
        
        # For longer completions, allow proportional variance
        if delta_len > 10 and abs(x_move - delta_len) <= (delta_len * 0.2):
            return True
        
        return False

    def _detect_completion_patterns(self, delta_text):
        """Detect common tab completion patterns (duplicated from main command)"""
        if not delta_text:
            return False
        
        delta_stripped = delta_text.strip()
        
        # File extension completion
        if '.' in delta_stripped and delta_stripped.count('.') <= 2:
            return True
        
        # Path completion
        if '/' in delta_stripped or '\\' in delta_stripped:
            return True
        
        # Command parameter completion
        if delta_stripped.startswith('-') and len(delta_stripped) > 1:
            return True
        
        # Word boundary completion
        if delta_stripped.isalnum() and len(delta_stripped) >= 2:
            return True
        
        return False

    def set_callback(self, callback):
        pass