"""cortex/api/routes/curiosity_seeds.py — Curiosity Seeds CRUD endpoints.

Provides admin-gated endpoints for managing curated curiosity seeds
that feed the Deep Dream phase (#772).

Endpoints:
  GET  /api/v1/curiosity-seeds       — List active seeds (filterable)
  POST /api/v1/curiosity-seeds       — Create a new seed (admin)
  GET  /api/v1/dreams                — List dreams (with quality scores)
  GET  /api/v1/dreams/{dream_id}     — Get a single dream
"""

from __future__ import annotations

import json
import logging
import uuid
from datetime import datetime, timezone
from typing import Any, Dict, Optional

from fastapi import APIRouter, Depends, HTTPException, Query, status
from fastapi.responses import JSONResponse

from cortex.api.deps import PREFIX, get_plugin

logger = logging.getLogger(__name__)

router = APIRouter()


def _make_routes(verify_api_key):
    """Create routes with auth dependency injection."""

    # ── GET /api/v1/curiosity-seeds ─────────────────────────────────

    @router.get(
        f"{PREFIX}/curiosity-seeds",
        summary="List curiosity seeds",
        operation_id="list_curiosity_seeds",
        dependencies=[Depends(verify_api_key)],
    )
    async def list_curiosity_seeds(
        active: Optional[bool] = Query(None, description="Filter by active status"),
        source: Optional[str] = Query(None, description="Filter by source (manual/extracted)"),
        category: Optional[str] = Query(None, description="Filter by category"),
        limit: int = Query(50, ge=1, le=200),
        plugin=Depends(get_plugin),
    ):
        """List curiosity seeds, optionally filtered by active/source/category."""
        try:
            conditions = ["owner_id = ?"]
            params: list = [getattr(plugin.config, "owner_id", "default")]

            if active is not None:
                conditions.append("active = ?")
                params.append(1 if active else 0)
            if source is not None:
                conditions.append("source = ?")
                params.append(source)
            if category is not None:
                conditions.append("category = ?")
                params.append(category)

            where = " AND ".join(conditions)
            rows = await plugin.storage.execute_fetchall(
                f"""SELECT id, content, category, source, active, priority,
                           explored_by_dream_id, created_at
                    FROM curiosity_seeds
                    WHERE {where}
                    ORDER BY priority DESC, created_at DESC
                    LIMIT ?""",
                (*params, limit),
            )

            seeds = [
                {
                    "id": r[0],
                    "content": r[1],
                    "category": r[2],
                    "source": r[3],
                    "active": bool(r[4]),
                    "priority": r[5],
                    "explored_by_dream_id": r[6],
                    "created_at": r[7],
                }
                for r in rows
            ]
            return {"seeds": seeds, "count": len(seeds)}

        except Exception as exc:
            logger.error("Failed to list curiosity seeds: %s", exc)
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=str(exc),
            )

    # ── POST /api/v1/curiosity-seeds ────────────────────────────────

    @router.post(
        f"{PREFIX}/curiosity-seeds",
        summary="Create a curiosity seed",
        operation_id="create_curiosity_seed",
        dependencies=[Depends(verify_api_key)],
        status_code=status.HTTP_201_CREATED,
    )
    async def create_curiosity_seed(
        body: Dict[str, Any],
        plugin=Depends(get_plugin),
    ):
        """Create a new curated curiosity seed for the Deep Dream phase."""
        content = body.get("content", "").strip()
        if not content:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="'content' is required and must be non-empty",
            )

        category = body.get("category", "philosophical")
        if category not in ("philosophical", "practical", "personal"):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="category must be 'philosophical', 'practical', or 'personal'",
            )

        source = body.get("source", "manual")
        if source not in ("manual", "extracted"):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="source must be 'manual' or 'extracted'",
            )

        priority = body.get("priority", 5)
        owner_id = getattr(plugin.config, "owner_id", "default")
        seed_id = f"seed-{uuid.uuid4().hex[:12]}"
        now = datetime.now(timezone.utc).isoformat()

        try:
            await plugin.storage.execute(
                """INSERT INTO curiosity_seeds
                   (id, content, category, source, active, priority, owner_id, created_at)
                   VALUES (?, ?, ?, ?, 1, ?, ?, ?)""",
                (seed_id, content, category, source, priority, owner_id, now),
            )
            await plugin.storage.commit()

            return {
                "id": seed_id,
                "content": content,
                "category": category,
                "source": source,
                "active": True,
                "priority": priority,
                "created_at": now,
            }
        except Exception as exc:
            logger.error("Failed to create curiosity seed: %s", exc)
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=str(exc),
            )

    # ── GET /api/v1/dreams ──────────────────────────────────────────

    @router.get(
        f"{PREFIX}/dreams",
        summary="List dreams",
        operation_id="list_dreams",
        dependencies=[Depends(verify_api_key)],
    )
    async def list_dreams(
        limit: int = Query(20, ge=1, le=100),
        plugin=Depends(get_plugin),
    ):
        """List deep dreams with quality scores."""
        try:
            owner_id = getattr(plugin.config, "owner_id", "default")
            rows = await plugin.storage.execute_fetchall(
                """SELECT id, seed_content, thread_id, depth_score,
                          discovery_score, emotional_resonance_score,
                          duration_ms, created_at, model_used
                   FROM dreams
                   WHERE owner_id = ?
                   ORDER BY created_at DESC
                   LIMIT ?""",
                (owner_id, limit),
            )

            dreams = [
                {
                    "id": r[0],
                    "seed_content": r[1],
                    "thread_id": r[2],
                    "depth_score": r[3],
                    "discovery_score": r[4],
                    "emotional_resonance_score": r[5],
                    "avg_quality": round((r[3] + r[4] + r[5]) / 3, 2),
                    "duration_ms": r[6],
                    "created_at": r[7],
                    "model_used": r[8],
                }
                for r in rows
            ]
            return {"dreams": dreams, "count": len(dreams)}

        except Exception as exc:
            logger.error("Failed to list dreams: %s", exc)
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=str(exc),
            )

    # ── GET /api/v1/dreams/{dream_id} ───────────────────────────────

    @router.get(
        f"{PREFIX}/dreams/{{dream_id}}",
        summary="Get a dream",
        operation_id="get_dream",
        dependencies=[Depends(verify_api_key)],
    )
    async def get_dream(
        dream_id: str,
        plugin=Depends(get_plugin),
    ):
        """Get full dream content including all sections."""
        try:
            owner_id = getattr(plugin.config, "owner_id", "default")
            rows = await plugin.storage.execute_fetchall(
                """SELECT id, seed_id, seed_content, thread_id, content,
                          what_i_found, what_i_think, what_i_feel, thread_output,
                          depth_score, discovery_score, emotional_resonance_score,
                          model_used, duration_ms, created_at, claim_id
                   FROM dreams
                   WHERE id = ? AND owner_id = ?""",
                (dream_id, owner_id),
            )

            if not rows:
                raise HTTPException(
                    status_code=status.HTTP_404_NOT_FOUND,
                    detail=f"Dream {dream_id!r} not found",
                )

            r = rows[0]
            return {
                "id": r[0],
                "seed_id": r[1],
                "seed_content": r[2],
                "thread_id": r[3],
                "content": r[4],
                "what_i_found": r[5],
                "what_i_think": r[6],
                "what_i_feel": r[7],
                "thread_output": r[8],
                "depth_score": r[9],
                "discovery_score": r[10],
                "emotional_resonance_score": r[11],
                "avg_quality": round((r[9] + r[10] + r[11]) / 3, 2),
                "model_used": r[12],
                "duration_ms": r[13],
                "created_at": r[14],
                "claim_id": r[15],
            }

        except HTTPException:
            raise
        except Exception as exc:
            logger.error("Failed to get dream: %s", exc)
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=str(exc),
            )
