"""
reasoning.py
------------
API routes for contradiction detection and counterfactual edges.
"""

from __future__ import annotations

from typing import Any, Literal, Optional

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, Field

from hieromem_api.auth import require_api_key, require_permission
from hieromem_api.deps import get_memory_engine
from hieromem_api.rbac import Permission
from hieromem_api.tenants import Tenant, canonical_namespace, resolve_tenant
from hieromem_core.reasoning.contradiction import ContradictionDetector
from hieromem_core.reasoning.counterfactual import (
    COUNTERFACTUAL_RELATIONS,
    add_counterfactual_edge,
)

router = APIRouter(prefix="/reasoning", tags=["Reasoning"])

memory = get_memory_engine()


class ContradictionRequest(BaseModel):
    namespace: Optional[str] = None
    temporal_tolerance_seconds: float = Field(0.0, ge=0.0)


class CounterfactualRequest(BaseModel):
    source_episode_id: str
    target_episode_id: str
    relation: Literal["contradicts", "supersedes", "obsoletes"]
    namespace: Optional[str] = None
    weight: float = Field(1.0, ge=0.0)
    metadata: Optional[dict[str, Any]] = None


@router.post("/contradictions")
def contradictions(
    req: ContradictionRequest,
    tenant: Tenant = Depends(require_api_key),
    _perm_check: None = Depends(require_permission(Permission.READ_MEMORY)),
) -> dict[str, Any]:
    tenant = resolve_tenant(tenant)
    namespace = canonical_namespace(tenant, req.namespace)
    with memory.use_namespace(namespace):
        episodes = list(memory.episodes)
        # Use ContradictionDetector to find contradictions
        detector = ContradictionDetector()
        found_contradictions = detector.find_contradictions(episodes)

        result = {
            "contradictions": [c.to_dict() for c in found_contradictions],
            "count": len(found_contradictions),
            "namespace": req.namespace
        }
    return result


@router.post("/counterfactual")
def add_counterfactual(
    req: CounterfactualRequest,
    tenant: Tenant = Depends(require_api_key),
    _perm_check: None = Depends(require_permission(Permission.WRITE_MEMORY)),
) -> dict[str, Any]:
    tenant = resolve_tenant(tenant)
    namespace = canonical_namespace(tenant, req.namespace)

    if req.relation not in COUNTERFACTUAL_RELATIONS:
        raise HTTPException(status_code=400, detail="Unsupported counterfactual relation")

    with memory.use_namespace(namespace):
        source = memory._get_episode_by_id(req.source_episode_id)
        target = memory._get_episode_by_id(req.target_episode_id)
        if source is None or target is None:
            raise HTTPException(status_code=404, detail="Episode not found")
        attrs = add_counterfactual_edge(
            memory.graph_store,
            req.source_episode_id,
            req.target_episode_id,
            req.relation,
            namespace=namespace,
            weight=req.weight,
            metadata=req.metadata,
        )
        memory._bump_revision()

    return {
        "source_episode_id": req.source_episode_id,
        "target_episode_id": req.target_episode_id,
        "relation": req.relation,
        "namespace": req.namespace,
        "attributes": attrs,
    }
