"""Task: bulk re-embed all vectors for a project after a plan upgrade.

Triggered when workspace plan changes and the new embedding model has different
dimensions (e.g. free → pro: 768 → 1536). Existing vectors are incompatible and
must be regenerated before semantic search works correctly.

Flow:
1. Fetch all embed configs for the project
2. For each config: queue ai.embed for every record in that entity
3. Update workspace_vectorize_config.needs_reembed = False when complete
"""
from __future__ import annotations

import structlog
from uuid import UUID

logger = structlog.get_logger()


async def ai_reembed(ctx: dict, project_id: str) -> dict:
    """Arq worker entry point — bulk re-embed all configured entity fields."""
    from src.core.database import async_session_factory
    from src.domain.ai.repository import (
        ProjectAIEmbedConfigRepository,
        WorkspaceVectorizeConfigRepository,
    )
    from src.domain.projects.repository import ProjectRepository

    db_factory = ctx.get("db_factory", async_session_factory)
    pid = UUID(project_id)

    async with db_factory() as db:
        project = await ProjectRepository(db).get_by_id(pid)
        if not project:
            logger.warning("ai_reembed_skip", reason="project_not_found", project_id=project_id)
            return {"status": "skipped", "reason": "project_not_found"}

        embed_configs = await ProjectAIEmbedConfigRepository(db).list_for_project(pid)
        if not embed_configs:
            logger.info("ai_reembed_nothing", project_id=project_id)
            return {"status": "nothing_to_embed"}

        # Cloud handles the actual re-embed via its internal job queue
        # Core triggers the job; Cloud processes it asynchronously
        from src.integrations.cloud_control_client import CloudControlClient
        from src.integrations.cloud_control_client import get_cloud_client_for_workspace

        cloud = await get_cloud_client_for_workspace(project.workspace_id, db)
        configs = [
            {"entity_key": c.entity_key, "field_key": c.field_key}
            for c in embed_configs
        ]
        await cloud.trigger_bulk_reembed(
            project_id=project_id,
            embed_configs=configs,
        )

        # Clear the needs_reembed flag once the job is dispatched
        vec_repo = WorkspaceVectorizeConfigRepository(db)
        vec_cfg = await vec_repo.get_by_workspace(project.workspace_id)
        if vec_cfg and vec_cfg.needs_reembed:
            await vec_repo.update(vec_cfg, needs_reembed=False)

        await db.commit()

    logger.info("ai_reembed_dispatched", project_id=project_id, config_count=len(embed_configs))
    return {"status": "dispatched", "config_count": len(embed_configs)}


async def enqueue_reembed(project_id: str) -> None:
    """Enqueue a bulk re-embed job via arq."""
    from src.core.redis import get_redis
    from arq import ArqRedis

    redis = await get_redis()
    arq_redis = ArqRedis(redis.connection_pool)
    await arq_redis.enqueue_job("ai_reembed", project_id)
