"""
Configuration et dictionnaires multilingues pour mkdocs-superquiz
"""

import json
from pathlib import Path
from typing import Any, Dict, List, Optional


DEFAULTS_ALIASES = ("defaults", "global")


# ─────────────────────────────────────────────────────────────────────────────
# i18n helpers
# ─────────────────────────────────────────────────────────────────────────────

def load_i18n_config(language='en'):
    i18n_dir = Path(__file__).parent / 'i18n'
    i18n_file = i18n_dir / f'{language}.json'
    if not i18n_file.exists():
        i18n_file = i18n_dir / 'en.json'
    with open(i18n_file, 'r', encoding='utf-8') as f:
        return json.load(f)


def _merge_dedup_ci(primary_list, secondary_list):
    out = []
    seen = set()
    for src in (primary_list or []) + (secondary_list or []):
        s = str(src).strip()
        if not s:
            continue
        key = s.lower()
        if key in seen:
            continue
        seen.add(key)
        out.append(s)
    return out


def build_quiz_types_dict(language='en'):
    cfg_lang = load_i18n_config(language)
    cfg_en   = load_i18n_config('en')
    quiz_types = {}
    all_types = set((cfg_en.get('quiz_types', {}) or {}).keys()) | \
                set((cfg_lang.get('quiz_types', {}) or {}).keys())
    for quiz_type in all_types:
        en_syn   = (cfg_en.get('quiz_types', {}).get(quiz_type, {}) or {}).get('synonyms', []) or []
        lang_syn = (cfg_lang.get('quiz_types', {}).get(quiz_type, {}) or {}).get('synonyms', []) or []
        quiz_types[quiz_type] = _merge_dedup_ci(lang_syn, en_syn)
    return quiz_types


def build_keywords_dict(language='en'):
    cfg_lang = load_i18n_config(language).get('quiz_configs', {}) or {}
    cfg_en   = load_i18n_config('en').get('quiz_configs', {}) or {}

    def merged(key_name, default_list):
        lang_list = cfg_lang.get(key_name, default_list) or []
        en_list   = cfg_en.get(key_name, default_list) or []
        return _merge_dedup_ci(lang_list, en_list)

    return {
        'preamble': merged('preamble_keywords', ['preamble', 'pre']),
        'question': merged('question_keywords',  ['question', 'q']),
        'answers':  merged('answers_keywords',   ['answers', 'ans']),
    }


QUIZ_TYPES = build_quiz_types_dict('en')
KEYWORDS   = build_keywords_dict('en')


# ─────────────────────────────────────────────────────────────────────────────
# compare_answers — new format only (no legacy)
# ─────────────────────────────────────────────────────────────────────────────

# ─────────────────────────────────────────────────────────────────────────────
# Default compare_answers settings.
# These are the fallback values when no config is provided at any level.
# Override at any level:
#   - globally in mkdocs.yml under plugins > superquiz > fillblanks > compare_answers
#   - per-page in the page front-matter (not yet implemented)
#   - per-quiz in the quiz front-matter (between --- delimiters)
#   - per-question in the question mini front-matter (between --- delimiters)
# ─────────────────────────────────────────────────────────────────────────────
DEFAULT_COMPARE_ANSWERS: Dict[str, Any] = {
    "ignore": {
        "spaces":     "none",        # "none" | "outside" | "inside" | "all"
        "characters": "",            # string of characters to strip (e.g. "?,.;/:!¡-_")
        "case":       False,         # False = case-sensitive (default), True = case-insensitive
        "diacritics": False          # False = diacritics matter (default), True = ignore them
    },
    "equivalence": {}
}

_VALID_SPACES = frozenset(('all', 'inside', 'outside', 'none'))


def normalize_compare_answers(raw: Any) -> Dict[str, Any]:
    """
    Normalize a compare_answers config dict to canonical format:

        {
            "ignore": {
                "spaces":     "all" | "inside" | "outside" | "none",
                "characters": "<string>",
                "case":       True | False,
                "diacritics": True | False
            },
            "equivalence": { "base": ["variant", ...], ... }
        }

    Only the new format { ignore: {...}, equivalence: {...} } is accepted.
    Missing keys fall back to defaults. None / empty → returns defaults.
    """
    import copy

    if not raw or not isinstance(raw, dict):
        return copy.deepcopy(DEFAULT_COMPARE_ANSWERS)

    ignore = dict(DEFAULT_COMPARE_ANSWERS['ignore'])
    raw_ignore = raw.get('ignore', {})
    if isinstance(raw_ignore, dict):
        ignore.update(raw_ignore)

    if ignore.get('spaces') not in _VALID_SPACES:
        ignore['spaces'] = 'none'

    equivalence = _normalize_equivalence(raw.get('equivalence', {}))

    return {'ignore': ignore, 'equivalence': equivalence}


# def _normalize_equivalence(raw_equiv: Any) -> Dict[str, List[str]]:
#     """Normalize equivalence dict: all values become lists of strings."""
#     if not isinstance(raw_equiv, dict):
#         return {}
#     out: Dict[str, List[str]] = {}
#     for base, variants in raw_equiv.items():
#         if isinstance(variants, str):
#             out[str(base)] = [variants]
#         elif isinstance(variants, list):
#             out[str(base)] = [str(v) for v in variants]
#         else:
#             out[str(base)] = [str(variants)]
#     return out

def _normalize_equivalence(raw_equiv: Any) -> Dict[str, List[str]]:
    """Normalize equivalence dict: all values become lists of strings."""
    if not isinstance(raw_equiv, dict):
        return {}
    out: Dict[str, List[str]] = {}
    for base, variants in raw_equiv.items():
        if isinstance(variants, str):
            # ✅ Tenter de parser comme JSON si ça ressemble à une liste
            stripped = variants.strip()
            if stripped.startswith('['):
                try:
                    parsed = json.loads(stripped)
                    if isinstance(parsed, list):
                        out[str(base)] = [str(v) for v in parsed]
                        continue
                except (json.JSONDecodeError, ValueError):
                    pass
            out[str(base)] = [variants]
        elif isinstance(variants, list):
            out[str(base)] = [str(v) for v in variants]
        else:
            out[str(base)] = [str(variants)]
    return out


# ─────────────────────────────────────────────────────────────────────────────
# DEFAULT_CONFIG
# ─────────────────────────────────────────────────────────────────────────────

DEFAULT_CONFIG = {
    'security_mode': 'obfuscated',
    'teacher_code': None,
    'encryption_key': 'default-key-change-me',
    'api_endpoint': None,
    'correction_granularity': 'exercise',

    'min_score': None,
    'clamp_max_score': True,

    'correction_locked_icon':   '❌',
    'correction_unlock_icon':   '🔐',
    'correction_unlocked_icon': '✅',

    'mcquiz': {
        'scoring_mode':        'proportional',
        'default_false':       0,
        'default_points':      1,
        'show_correction':     'on_demand',
        'save_answers':        True,
        'randomize_questions': False,
        'randomize_answers':   False,
        'synonyms':            []
    },

    'scquiz': {
        'scoring_mode':        'all_or_nothing',
        'default_false':       0,
        'default_points':      1,
        'show_correction':     'on_demand',
        'save_answers':        True,
        'randomize_questions': False,
        'randomize_answers':   False,
        'synonyms':            []
    },

    'fillblanks': {
        'scoring_mode':        'proportional',
        'default_false':       0,
        'default_points':      1,
        'show_correction':     'on_demand',
        'save_answers':        True,
        'randomize_questions': False,
        'synonyms':            [],
        # compare_answers defaults for fillblanks — override in mkdocs.yml, per-page,
        # per-quiz front-matter, or per-question front-matter.
        # The values here mirror DEFAULT_COMPARE_ANSWERS above.
        'compare_answers': {
            'ignore': {
                'spaces':     'none',   # "none" | "outside" | "inside" | "all"
                'characters': '',       # e.g. '?,.;/:!¡-_' to strip punctuation
                'case':       False,    # False = case-sensitive, True = insensitive
                'diacritics': False     # False = diacritics matter, True = ignore
            },
            'equivalence': {}
        }
    },

    # ✅ scdropdown: randomize_options renommé en randomize_answers
    #    randomize_questions ajouté
    'scdropdown': {
        'scoring_mode':        'all_or_nothing',
        'default_false':       0,
        'default_points':      1,
        'show_correction':     'on_demand',
        'save_answers':        True,
        'randomize_questions': False,
        'randomize_answers':   False,
        'synonyms':            []
    }
}


# ─────────────────────────────────────────────────────────────────────────────
# Helpers
# ─────────────────────────────────────────────────────────────────────────────

def normalize_quiz_type(quiz_type_str: str, language: str = 'en') -> Optional[str]:
    quiz_types = build_quiz_types_dict(language)
    quiz_type_lower = quiz_type_str.lower()
    for canonical_type, synonyms in quiz_types.items():
        if quiz_type_lower in [s.lower() for s in synonyms]:
            return canonical_type
    return None


def normalize_keyword(keyword_str: str, language: str = 'en') -> Optional[str]:
    import re
    keywords = build_keywords_dict(language)
    keyword_base = re.sub(r'\d+$', '', keyword_str.lower())
    for canonical_keyword, synonyms in keywords.items():
        if keyword_base in [s.lower() for s in synonyms]:
            return canonical_keyword
    return None
