from __future__ import annotations

from typing import Any

from app.agents.registry import AGENT_REGISTRY


class ReviewMemoryHelpersMixin:
    """Helper methods for metadata formatting and serialization."""

    def _resolve_task_type(metadata: Any, fallback: Any = None) -> str | None:
        """Resolve a supported task type from metadata or fallback agent hints."""
        values: list[str] = []
        if isinstance(metadata, dict):
            for key in ("task_type", "agent_scope", "primary_task_type"):
                value = metadata.get(key)
                if isinstance(value, str) and value.strip():
                    values.append(value.strip())
        if isinstance(fallback, str) and fallback.strip():
            values.append(fallback.strip())

        for value in values:
            if value in AGENT_REGISTRY:
                return value
        return None

    def _base_metadata(
        *,
        task_type: str,
        project_code: Any,
        agent_scope: Any,
        document_type: Any,
        knowledge_type: str,
        source_table: str,
        review_id: Any = None,
        finding_id: Any = None,
        assignment_id: Any = None,
    ) -> dict[str, Any]:
        """Build normalized metadata for Qdrant payload storage."""
        metadata: dict[str, Any] = {
            "task_type": task_type,
            "project_code": str(project_code or ""),
            "agent_scope": str(agent_scope or ""),
            "document_type": str(document_type or ""),
            "knowledge_type": knowledge_type,
            "source_table": source_table,
        }
        if review_id:
            metadata["review_id"] = str(review_id)
        if finding_id:
            metadata["finding_id"] = str(finding_id)
        if assignment_id:
            metadata["assignment_id"] = str(assignment_id)
        return metadata

    def _normalize_metadata(metadata: Any) -> dict[str, Any]:
        """Keep only scalar metadata values that work well as retrieval filters."""
        if not isinstance(metadata, dict):
            return {}

        normalized: dict[str, Any] = {}
        for key, value in metadata.items():
            if value is None or value == "":
                continue
            if isinstance(value, (str, int, float, bool)):
                normalized[key] = value
        return normalized

    def _prefixed(label: str, value: Any) -> str:
        """Return a labelled text line when the value exists."""
        if value is None:
            return ""
        text = str(value).strip()
        if not text:
            return ""
        return f"{label}: {text}"

    def _join_lines(lines: list[str]) -> str:
        """Join non-empty text lines into a chunk body."""
        return "\n".join([line for line in lines if line])

    def _compact_sentence(parts: list[Any]) -> str:
        """Join small text fragments into a readable one-line summary."""
        values = [
            str(part).strip()
            for part in parts
            if part is not None and str(part).strip()
        ]
        return " - ".join(values)

    def _serialize_state(state: Any) -> str:
        """Serialize simple state dictionaries into compact retrieval text."""
        if not isinstance(state, dict) or not state:
            return ""
        return "; ".join(
            f"{key}={value}"
            for key, value in state.items()
            if value is not None and value != ""
        )
