"""Indexer — batch-indexes existing Odoo records into the vector store."""

import logging

_logger = logging.getLogger(__name__)

MODEL_CONFIG = [
    {
        'model': 'op.course',
        'content_type': 'course',
        'text_field': 'name',
        'description_field': 'description',
        'metadata_fields': [],
    },
    {
        'model': 'encoach.resource',
        'content_type': 'resource',
        'text_field': 'name',
        'description_field': 'content',
        'metadata_fields': ['type', 'cefr_level', 'difficulty'],
    },
    {
        'model': 'encoach.question',
        'content_type': 'question',
        'text_field': 'name',
        'description_field': None,
        'metadata_fields': ['question_type', 'difficulty', 'skill'],
    },
    {
        'model': 'encoach.course.module',
        'content_type': 'module',
        'text_field': 'name',
        'description_field': 'description',
        'metadata_fields': ['skill'],
    },
    {
        'model': 'encoach.ai.generation.log',
        'content_type': 'generation_log',
        'text_field': 'brief',
        'description_field': 'generated_content',
        'metadata_fields': ['course_type', 'status'],
    },
]


def _get_text(record, config):
    """Extract indexable text from a record."""
    parts = []
    text_field = config.get('text_field', 'name')
    if hasattr(record, text_field):
        val = getattr(record, text_field)
        if val:
            parts.append(str(val))

    desc_field = config.get('description_field')
    if desc_field and hasattr(record, desc_field):
        val = getattr(record, desc_field)
        if val:
            parts.append(str(val)[:2000])

    return ' '.join(parts).strip()


def _get_metadata(record, config):
    """Extract metadata dict from a record."""
    meta = {}
    for f in config.get('metadata_fields', []):
        if hasattr(record, f):
            val = getattr(record, f)
            if val:
                meta[f] = str(val) if not isinstance(val, (int, float, bool)) else val
    return meta


def index_model(env, config, batch_size=100):
    """Index all records of a single model."""
    model_name = config['model']
    Model = env.get(model_name)
    if Model is None:
        _logger.warning("Model %s not found, skipping", model_name)
        return 0

    Model = Model.sudo()

    from .embedding_service import EmbeddingService
    svc = EmbeddingService(env)

    total = Model.search_count([])
    indexed = 0
    offset = 0

    while offset < total:
        records = Model.search([], limit=batch_size, offset=offset, order='id')
        batch_data = []
        for rec in records:
            text = _get_text(rec, config)
            if text:
                batch_data.append({
                    'id': rec.id,
                    'text': text,
                    'metadata': _get_metadata(rec, config),
                })
        if batch_data:
            indexed += svc.bulk_index(config['content_type'], batch_data)
        offset += batch_size
        env.cr.commit()

    _logger.info("Indexed %d/%d records for %s", indexed, total, model_name)
    return indexed


def index_all(env, batch_size=100):
    """Index all configured models."""
    total = 0
    for config in MODEL_CONFIG:
        try:
            total += index_model(env, config, batch_size)
        except Exception:
            _logger.exception("Failed to index %s", config['model'])
    _logger.info("Total records indexed: %d", total)
    return total


def cron_reindex(env):
    """Cron entry point for periodic re-indexing."""
    _logger.info("Starting scheduled vector re-index")
    return index_all(env)
