"""Floor manager for controlling speaking order."""

from collections import deque
from typing import Optional

from thetable_poc.core import Participant


class FloorManager:
    """Manages speaking floor (who can speak when)."""

    def __init__(self):
        """Initialize floor manager."""
        self._current_speaker: Optional[Participant] = None
        self._speaker_queue: deque[Participant] = deque()
        self._user_has_floor: bool = False
        self._dialogue_mode: bool = False
        self._dialogue_initiator: Optional[Participant] = None

    @property
    def current_speaker(self) -> Optional[Participant]:
        """Get current speaker."""
        return self._current_speaker

    @property
    def user_has_floor(self) -> bool:
        """Check if user has the floor."""
        return self._user_has_floor

    def grant_floor(self, participant: Participant) -> None:
        """Grant floor to a participant.

        Args:
            participant: Participant to grant floor to
        """
        self._current_speaker = participant
        if participant.is_human:
            self._user_has_floor = True

    def release_floor(self) -> None:
        """Release the current floor."""
        self._current_speaker = None
        self._user_has_floor = False

    def request_floor(self, participant: Participant) -> None:
        """Request floor for a participant.

        Args:
            participant: Participant requesting floor
        """
        if participant not in self._speaker_queue:
            self._speaker_queue.append(participant)

    def get_next_speaker(self) -> Optional[Participant]:
        """Get next speaker from queue.

        Returns:
            Next participant or None if queue is empty
        """
        if self._speaker_queue:
            return self._speaker_queue.popleft()
        return None

    def has_pending_speakers(self) -> bool:
        """Check if there are pending speakers.

        Returns:
            True if speaker queue is not empty
        """
        return len(self._speaker_queue) > 0

    def clear_queue(self) -> None:
        """Clear the speaker queue."""
        self._speaker_queue.clear()

    def interrupt_for_user(self) -> None:
        """Interrupt current speaker for user input."""
        self._user_has_floor = True

    def resume_after_user(self) -> None:
        """Resume normal meeting flow after user interruption.

        Releases user floor and allows AI participants to speak again.
        """
        self._user_has_floor = False

    def can_speak(self, participant: Participant) -> bool:
        """Check if participant can speak now.

        Args:
            participant: Participant to check

        Returns:
            True if participant can speak
        """
        # User can always speak
        if participant.is_human:
            return True

        # If user has floor, AI cannot speak
        if self._user_has_floor:
            return False

        # If no current speaker, can speak
        if self._current_speaker is None:
            return True

        # Can speak if they are the current speaker
        return self._current_speaker == participant

    def select_next_responder(
        self,
        participants: list[Participant],
        context: dict,
    ) -> Optional[Participant]:
        """Select next responder based on context.

        Args:
            participants: List of all participants
            context: Context including recent messages, phase, etc.

        Returns:
            Selected participant or None
        """
        # Check if user mentioned someone by name
        last_message = context.get("last_message", "")
        for p in participants:
            if p.name.lower() in last_message.lower():
                return p

        # Check speaker queue first
        if self.has_pending_speakers():
            return self.get_next_speaker()

        # Phase-based selection
        phase = context.get("phase")
        if phase == "opening" or phase == "closing":
            # Host speaks in opening/closing
            for p in participants:
                if p.role.value == "host":
                    return p

        elif phase == "status_check":
            # PM speaks in status check
            for p in participants:
                if p.role.value == "pm":
                    return p

        elif phase == "issue_resolution":
            # Tech lead speaks in issue resolution
            for p in participants:
                if p.role.value == "tech_lead":
                    return p

        # Default: return None (will be handled by caller)
        return None

    @property
    def in_dialogue_mode(self) -> bool:
        """Check if currently in dialogue mode.
        
        Returns:
            True if in dialogue mode, False otherwise
        """
        return self._dialogue_mode

    @property
    def dialogue_initiator(self) -> Optional[Participant]:
        """Get the participant who initiated current dialogue.
        
        Returns:
            Dialogue initiator or None if not in dialogue mode
        """
        return self._dialogue_initiator

    def enter_dialogue_mode(self, initiator: Participant) -> None:
        """Enter dialogue mode with given initiator.
        
        Args:
            initiator: Participant who initiated the dialogue
        """
        self._dialogue_mode = True
        self._dialogue_initiator = initiator

    def exit_dialogue_mode(self) -> None:
        """Exit dialogue mode and clear initiator."""
        self._dialogue_mode = False
        self._dialogue_initiator = None
