"""cortex/api/routes/admin/owners.py — Owner management endpoints."""

from __future__ import annotations

import logging
from typing import Any, Dict, List

from fastapi import APIRouter, Depends

from cortex.api.deps import PREFIX, get_plugin
from cortex.api.models import AdminOwnersResponse, AdminReindexResponse

logger = logging.getLogger(__name__)


def _register(router: APIRouter, verify_api_key):
    """Register owner management routes on the given router."""

    # ---- #824: GET /admin/owners ----

    @router.get(
        f"{PREFIX}/admin/owners",
        response_model=AdminOwnersResponse,
        summary="List all owner_ids with claim counts",
        tags=["admin"],
        operation_id="admin_list_owners",
    )
    async def admin_list_owners(
        _: None = Depends(verify_api_key),
        plugin: Any = Depends(get_plugin),
    ) -> AdminOwnersResponse:
        """List all distinct owner_ids with their active claim counts."""
        errors: List[str] = []
        storage = getattr(plugin, "storage", None)
        if storage is None:
            return AdminOwnersResponse(errors=["Storage not available"])
        owners: List[Dict[str, Any]] = []
        try:
            conn = await storage._get_conn()
            async with conn.execute(
                "SELECT owner_id, COUNT(*) AS claim_count FROM semantic_claim"
                " WHERE (is_deleted = 0 OR is_deleted IS NULL)"
                " GROUP BY owner_id ORDER BY claim_count DESC"
            ) as cur:
                rows = await cur.fetchall()
            owners = [{"owner_id": row[0], "claim_count": row[1]} for row in rows]
        except Exception as exc:
            errors.append(f"Owners list failed: {exc}")
            logger.error("admin_list_owners: %s", exc, exc_info=True)
        return AdminOwnersResponse(owners=owners, total_owners=len(owners), errors=errors)

    # ---- #824: POST /admin/owners/{owner_id}/reindex ----

    @router.post(
        f"{PREFIX}/admin/owners/{{owner_id}}/reindex",
        response_model=AdminReindexResponse,
        summary="Trigger re-embedding for all claims of an owner",
        tags=["admin"],
        operation_id="admin_reindex_owner",
    )
    async def admin_reindex_owner(
        owner_id: str,
        _: None = Depends(verify_api_key),
        plugin: Any = Depends(get_plugin),
    ) -> AdminReindexResponse:
        """Queue a background re-embedding job for all claims owned by owner_id."""
        import uuid as _uuid, asyncio as _asyncio
        errors: List[str] = []
        storage = getattr(plugin, "storage", None)
        if storage is None:
            return AdminReindexResponse(job_id="", owner_id=owner_id, claims_queued=0,
                                        status="error", errors=["Storage not available"])
        job_id = str(_uuid.uuid4())
        try:
            conn = await storage._get_conn()
            async with conn.execute(
                "SELECT id, subject, predicate, object_value FROM semantic_claim WHERE owner_id = ?"
                " AND status != 'deleted' ORDER BY created_at ASC",
                (owner_id,),
            ) as cur:
                claim_rows = await cur.fetchall()
            claims_queued = len(claim_rows)
            if claims_queued == 0:
                return AdminReindexResponse(job_id=job_id, owner_id=owner_id,
                                            claims_queued=0, status="noop", errors=[])
            async def _reindex_task():
                llm = getattr(plugin, "llm", None)
                if llm is None or not hasattr(llm, "embed"):
                    logger.warning("reindex_owner: no LLM embed for job %s", job_id)
                    return
                embed_model = getattr(plugin.config, "embedding_model", "voyage-4-large")
                for claim_id, subject, predicate, object_value in claim_rows:
                    content = f"{subject} {predicate} {object_value}"
                    try:
                        resp = await llm.embed(texts=[content], input_type="document")
                        if resp and resp.embeddings:
                            await storage.store_embedding(item_type="claim", item_id=claim_id,
                                                          embedding=resp.embeddings[0], model_id=embed_model)
                    except Exception as emb_exc:
                        logger.warning("reindex embed failed claim=%s job=%s: %s",
                                       claim_id, job_id, emb_exc)
            _asyncio.ensure_future(_reindex_task())
        except Exception as exc:
            errors.append(f"Reindex setup failed: {exc}")
            logger.error("admin_reindex_owner: %s", exc, exc_info=True)
            return AdminReindexResponse(job_id=job_id, owner_id=owner_id,
                                        claims_queued=0, status="error", errors=errors)
        return AdminReindexResponse(job_id=job_id, owner_id=owner_id,
                                    claims_queued=claims_queued, status="queued", errors=errors)
