"""v0.3 consolidation with advanced CoT reasoning and cross-domain insights."""

from __future__ import annotations

import time

from neurovault.cognitive.advanced_llm import AdvancedLLMConsolidation
from neurovault.cognitive.consolidation_v2 import ConsolidationEngineV2
from neurovault.models import ConsolidationReport


class ConsolidationEngineV3(ConsolidationEngineV2):
    """v0.3 consolidation engine."""

    def __init__(self, storage, chronos_bridge, extractor=None, llm_client=None, calibrator=None):
        super().__init__(storage, chronos_bridge, extractor=extractor, llm_client=llm_client, calibrator=calibrator)
        self._advanced = AdvancedLLMConsolidation(self._llm)

    def run(self, force: bool = False, phases: list[str] | None = None) -> ConsolidationReport:
        del force
        start = time.time()
        report = ConsolidationReport()
        all_phases = phases or [
            "entities",
            "llm_relations",
            "clusters",
            "insights",
            "cross_domain",
            "promote",
            "decay",
            "calibrate",
        ]

        if "entities" in all_phases:
            report.entities_extracted, report.relationships_found = self._phase1_entities()

        if "llm_relations" in all_phases and self._llm_available:
            report.relationships_found += self._phase1b_llm_relationships()

        if "clusters" in all_phases:
            report.clusters_formed = self._phase2_clusters()

        if "insights" in all_phases:
            report.insights_generated = self._phase3_insights_v3()

        if "cross_domain" in all_phases and self._llm_available:
            report.cross_domain_insights = self._phase7_cross_domain()

        if "promote" in all_phases:
            report.memories_promoted = self._phase4_promotion()

        if "decay" in all_phases:
            report.memories_decayed, report.memories_archived = self._phase5_decay()

        if "calibrate" in all_phases:
            self._phase6_calibrate()

        report.duration_seconds = time.time() - start
        self._bridge.checkpoint(
            f"v0.3 Consolidation: {report.entities_extracted} entities, "
            f"{report.relationships_found} rels, {report.insights_generated} insights, "
            f"{report.cross_domain_insights} cross-domain, {report.memories_decayed} decayed"
        )
        return report

    def _phase3_insights_v3(self) -> int:
        clusters = self._storage.get_clusters_without_insights()
        insights = 0

        for cluster in clusters:
            if len(cluster.memory_ids) < 3:
                continue

            texts, entity_names = self._gather_cluster_data(cluster)
            relationships = self._storage.get_relationships_for_cluster(cluster.id)

            cot_result = self._advanced.chain_of_thought_insight(
                memories=[{"content": text} for text in texts],
                entities=entity_names,
                relationships=[
                    {
                        "source": rel.source_entity_id.hex(),
                        "type": rel.relation_type,
                        "target": rel.target_entity_id.hex(),
                    }
                    for rel in relationships
                ],
            )

            insight_text = str(cot_result.get("insight", "")).strip()
            if len(insight_text) < 20:
                continue

            quality = self._advanced.quality_score_insight(insight_text)
            insight = self._bridge.store_memory(
                content=f"[CoT Insight] {insight_text}",
                source="consolidation",
                importance=quality,
                metadata={
                    "type": "insight",
                    "method": "chain-of-thought",
                    "quality_score": quality,
                    "reasoning_chain": cot_result.get("reasoning_chain", []),
                    "cluster_id": cluster.id.hex() if cluster.id else "",
                },
            )
            self._storage.set_cluster_insight(cluster.id, insight.id)
            insights += 1

        return insights

    def _phase7_cross_domain(self) -> int:
        clusters = self._storage.get_top_clusters(limit=10)
        cross_insights = 0

        for i in range(len(clusters)):
            for j in range(i + 1, len(clusters)):
                cluster_a = self._get_cluster_data(clusters[i])
                cluster_b = self._get_cluster_data(clusters[j])
                connection = self._advanced.cross_domain_association(cluster_a, cluster_b)
                if not connection:
                    continue

                self._bridge.store_memory(
                    content=f"[Cross-Domain] {connection['connection']}",
                    source="consolidation",
                    importance=0.9,
                    metadata={
                        "type": "cross-domain-insight",
                        **connection,
                    },
                )
                cross_insights += 1

        return cross_insights

    def _get_cluster_data(self, cluster) -> dict[str, str | list[str]]:
        texts, entities = self._gather_cluster_data(cluster)
        return {
            "id": cluster.id.hex() if cluster.id else "",
            "label": ", ".join(entities[:3]),
            "memory_samples": texts,
        }
