"""Mention parser for detecting @mentions in messages."""

import re
from dataclasses import dataclass

from thetable_poc.core import Participant, Role


@dataclass
class MentionResult:
    """Result of mention parsing.

    Attributes:
        mentioned_participants: List of participants mentioned
        is_everyone: True if @everyone or @모두 was used
        cleaned_message: Message with mentions removed
    """
    mentioned_participants: list[Participant]
    is_everyone: bool
    cleaned_message: str


def parse_mentions(message: str, participants: list[Participant]) -> MentionResult:
    """Parse @mentions from message.

    Supports:
    - @name (e.g., @Sarah, @John)
    - @role (e.g., @PM, @Tech_Lead)
    - @everyone / @모두
    - "name님," pattern (backward compatibility)

    Args:
        message: Message text to parse
        participants: List of available participants

    Returns:
        MentionResult with mentioned participants and cleaned message
    """
    mentioned = []
    is_everyone = False
    cleaned = message

    # Check for @everyone or @모두
    everyone_pattern = r'@(?:everyone|모두)\b'
    if re.search(everyone_pattern, message, re.IGNORECASE):
        is_everyone = True
        # Remove @everyone/@모두 from message
        cleaned = re.sub(everyone_pattern, '', cleaned, flags=re.IGNORECASE)
        return MentionResult(
            mentioned_participants=[],  # Will be filled by caller with all AI participants
            is_everyone=True,
            cleaned_message=cleaned.strip()
        )

    # Check for @name mentions
    # Pattern: @word (where word can be letters, numbers, underscore, dot, hyphen)
    # Supports names like "Mr.Yong", "sub-admin", etc.
    mention_pattern = r'@([\w.-]+)'
    matches = re.finditer(mention_pattern, message)

    for match in matches:
        mention_text = match.group(1).lower()

        # Try to match by name with flexible matching
        matched = False
        for participant in participants:
            participant_name_lower = participant.name.lower()

            # 1. Exact matching
            if participant_name_lower == mention_text:
                if participant not in mentioned:
                    mentioned.append(participant)
                cleaned = cleaned.replace(match.group(0), '', 1)
                matched = True
                break

            # 2. Partial matching (Mr.Yong → mr.yong, mryong)
            # Remove dots and spaces for comparison
            normalized_name = participant_name_lower.replace('.', '').replace(' ', '')
            normalized_mention = mention_text.replace('.', '').replace(' ', '')
            if normalized_mention in normalized_name or normalized_name in normalized_mention:
                if participant not in mentioned:
                    mentioned.append(participant)
                cleaned = cleaned.replace(match.group(0), '', 1)
                matched = True
                break

            # 3. First name matching (Sarah Kim → sarah)
            if participant_name_lower.startswith(mention_text):
                if participant not in mentioned:
                    mentioned.append(participant)
                cleaned = cleaned.replace(match.group(0), '', 1)
                matched = True
                break

        # If no name match, try to match by role
        if not matched:
            role_mentioned = _match_role(mention_text)
            if role_mentioned:
                for participant in participants:
                    if participant.role == role_mentioned:
                        if participant not in mentioned:
                            mentioned.append(participant)
                        # Remove mention from message
                        cleaned = cleaned.replace(match.group(0), '', 1)
                        break

    # Mentions must use @ symbol explicitly
    # No implicit mention patterns (like "님,") to avoid confusion with greetings
    
    return MentionResult(
        mentioned_participants=mentioned,
        is_everyone=False,
        cleaned_message=cleaned.strip()
    )


def _match_role(role_text: str) -> Role | None:
    """Match role text to Role enum.

    Args:
        role_text: Role text (case-insensitive)

    Returns:
        Matching Role or None
    """
    role_text = role_text.lower()

    role_map = {
        # Meeting operation
        'host': Role.HOST,

        # Project management
        'pm': Role.PM,

        # Technical leadership
        'tech_lead': Role.TECH_LEAD,
        'techlead': Role.TECH_LEAD,

        # Execution layer
        'backend': Role.BACKEND,
        'frontend': Role.FRONTEND,
        'qa': Role.QA,
        'tester': Role.QA,
        'devops': Role.DEVOPS,
        'security': Role.SECURITY,

        # Legacy aliases (map to BACKEND for backward compatibility)
        'developer': Role.BACKEND,
        'dev': Role.BACKEND,

        # General participant
        'member': Role.MEMBER,
        'user': Role.MEMBER,
        'participant': Role.MEMBER,
    }

    return role_map.get(role_text)
