"""Language detection and RTL/LTR utilities."""

import re
from typing import Tuple, Optional

# RTL languages - ISO 639-1 codes
RTL_LANGUAGES = {
    'ar',  # Arabic
    'he',  # Hebrew
    'fa',  # Persian/Farsi
    'ur',  # Urdu
    'yi',  # Yiddish
    'ps',  # Pashto
    'sd',  # Sindhi
    'ug',  # Uyghur
    'ku',  # Kurdish (when written in Arabic script)
    'dv',  # Divehi/Maldivian
    'arc', # Aramaic
    'syr', # Syriac
}

# RTL language names (for matching detected language names)
RTL_LANGUAGE_NAMES = {
    'arabic', 'hebrew', 'persian', 'farsi', 'urdu', 'yiddish',
    'pashto', 'sindhi', 'uyghur', 'kurdish', 'divehi', 'maldivian',
    'aramaic', 'syriac',
    # Arabic variants
    'العربية', 'עברית', 'فارسی', 'اردو',
}

# Unicode ranges for RTL scripts
RTL_UNICODE_RANGES = [
    (0x0590, 0x05FF),  # Hebrew
    (0x0600, 0x06FF),  # Arabic
    (0x0700, 0x074F),  # Syriac
    (0x0750, 0x077F),  # Arabic Supplement
    (0x0780, 0x07BF),  # Thaana (Maldivian)
    (0x07C0, 0x07FF),  # N'Ko
    (0x0800, 0x083F),  # Samaritan
    (0x0840, 0x085F),  # Mandaic
    (0x08A0, 0x08FF),  # Arabic Extended-A
    (0xFB50, 0xFDFF),  # Arabic Presentation Forms-A
    (0xFE70, 0xFEFF),  # Arabic Presentation Forms-B
]


def is_rtl_char(char: str) -> bool:
    """Check if a character is from an RTL script."""
    code_point = ord(char)
    for start, end in RTL_UNICODE_RANGES:
        if start <= code_point <= end:
            return True
    return False


def detect_text_direction(text: str) -> str:
    """
    Detect text direction based on character analysis.
    Returns 'rtl' or 'ltr'.
    """
    if not text:
        return 'ltr'

    # Count RTL vs LTR characters (excluding punctuation, numbers, spaces)
    rtl_count = 0
    ltr_count = 0

    # Sample first 1000 characters for efficiency
    sample = text[:1000]

    for char in sample:
        if is_rtl_char(char):
            rtl_count += 1
        elif char.isalpha():
            ltr_count += 1

    # If more than 30% RTL characters, treat as RTL
    total = rtl_count + ltr_count
    if total == 0:
        return 'ltr'

    rtl_ratio = rtl_count / total
    return 'rtl' if rtl_ratio > 0.3 else 'ltr'


def detect_language_from_text(text: str) -> Tuple[Optional[str], str]:
    """
    Detect language and text direction from text content.

    Returns:
        Tuple of (language_name, text_direction)
        language_name may be None if detection fails
    """
    if not text or len(text.strip()) < 10:
        return None, 'ltr'

    # First, detect direction from character analysis
    direction = detect_text_direction(text)

    # Try to detect specific language based on character patterns
    sample = text[:500]

    # Count characters from different scripts
    arabic_count = sum(1 for c in sample if 0x0600 <= ord(c) <= 0x06FF or 0xFB50 <= ord(c) <= 0xFEFF)
    hebrew_count = sum(1 for c in sample if 0x0590 <= ord(c) <= 0x05FF)
    persian_indicators = len(re.findall(r'[پچژگکی]', sample))  # Persian-specific chars

    # Detect based on script
    language = None

    if arabic_count > 50:
        if persian_indicators > 5:
            language = 'Persian'
        else:
            language = 'Arabic'
    elif hebrew_count > 50:
        language = 'Hebrew'
    elif direction == 'ltr':
        # For LTR, we could add more detection, but leave as None for now
        # The frontend can handle this gracefully
        pass

    return language, direction


def get_direction_for_language(language_code: str) -> str:
    """
    Get text direction for a language code.

    Args:
        language_code: ISO 639-1 language code (e.g., 'ar', 'he', 'en')

    Returns:
        'rtl' or 'ltr'
    """
    if not language_code:
        return 'ltr'

    code = language_code.lower().strip()

    # Check if it's an RTL language code
    if code in RTL_LANGUAGES:
        return 'rtl'

    # Check if it's an RTL language name
    if code in RTL_LANGUAGE_NAMES:
        return 'rtl'

    return 'ltr'


def normalize_language_info(language: Optional[str], text: str) -> Tuple[Optional[str], str]:
    """
    Normalize language info, detecting from text if not provided.

    Args:
        language: Detected or provided language (may be None)
        text: The text content

    Returns:
        Tuple of (language, text_direction)
    """
    # If we have a language, determine direction from it
    if language:
        direction = get_direction_for_language(language)
        return language, direction

    # Otherwise, detect from text
    return detect_language_from_text(text)
