from __future__ import annotations
from difflib import SequenceMatcher

class PhraseMatcher:
    def __init__(self, threshold: float = 0.72):
        self.threshold = threshold
        self.commands = {}

    def register(self, name: str, *phrases: str):
        self.commands.setdefault(name, [])
        self.commands[name].extend([p.strip().lower() for p in phrases])

    def match(self, text: str):
        raw = text.strip().lower()
        best = None
        best_score = 0.0
        for name, phrases in self.commands.items():
            for phrase in phrases:
                score = SequenceMatcher(None, raw, phrase).ratio()
                if raw == phrase:
                    return {"name": name, "phrase": phrase, "score": 1.0}
                if score > best_score:
                    best = {"name": name, "phrase": phrase, "score": score}
                    best_score = score
        if best and best["score"] >= self.threshold:
            return best
        return None

class VoiceCommand:
    def __init__(self, mode="hybrid", command_callback=None, free_callback=None, fuzzy_threshold=0.72):
        self.mode = mode
        self.matcher = PhraseMatcher(fuzzy_threshold)
        self.command_callback = command_callback
        self.free_callback = free_callback

    def register_phrase(self, name, *phrases):
        self.matcher.register(name, *phrases)

    def handle(self, text):
        match = self.matcher.match(text)
        if self.mode in {"commands", "hybrid"} and match:
            if self.command_callback:
                return self.command_callback(match["name"], text)
            return match
        if self.mode in {"free", "hybrid"} and self.free_callback:
            return self.free_callback(text)
        return None
