#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""
Conflict Monitor: Continuous contradiction detection (Phase 3).

Analogous to the Anterior Cingulate Cortex (ACC) — Botvinick et al. 2001.
Detects when new knowledge contradicts existing brain items and flags
conflicts for resolution instead of silently overwriting.

Runs as a consolidation stage, checking recently added items against
existing knowledge for semantic contradictions.
"""
import json
import logging
from datetime import datetime, timezone, timedelta

log = logging.getLogger("pulse.conflict_monitor")

# Contradiction signals
NEGATION_WORDS = {"never", "dont", "don't", "not", "avoid", "stop", "remove",
                  "wrong", "broken", "failed", "bad", "incorrect"}
AFFIRMATION_WORDS = {"always", "must", "should", "use", "add", "keep",
                     "correct", "works", "good", "right", "proper"}


def scan_for_conflicts(verbose: bool = False) -> dict:
    """Scan recent brain items for contradictions with existing knowledge.

    Checks items added in the last 24h against older items in the same domain.
    A contradiction is flagged when:
    1. Two items share high text similarity (>0.5)
    2. One contains negation signals and the other contains affirmation signals
    """
    try:
        from pulse.core.brain_db import get_conn
        from pulse.core.brain_utils import text_similarity
    except ImportError:
        return {"status": "skipped"}

    conn = get_conn()
    now = datetime.now(timezone.utc)
    day_ago = (now - timedelta(hours=24)).isoformat()
    conflicts = []

    for table in ["lessons", "failures", "patterns"]:
        try:
            # Get recent items
            recent = conn.execute(f"""
                SELECT id, title, content, domain FROM {table}
                WHERE timestamp > ? AND validity = 'valid'
                LIMIT 50
            """, (day_ago,)).fetchall()
            if not recent:
                continue
            # Get older items in same domains
            domains = {r["domain"] for r in recent if r["domain"]}
            if not domains:
                continue
            placeholders = ",".join("?" for _ in domains)
            older = conn.execute(f"""
                SELECT id, title, content, domain FROM {table}
                WHERE timestamp <= ? AND validity = 'valid'
                  AND domain IN ({placeholders})
                LIMIT 200
            """, (day_ago, *domains)).fetchall()

            for new_item in recent:
                new_text = (new_item["title"] or new_item["content"] or "").lower()
                if len(new_text) < 20:
                    continue
                new_words = set(new_text.split())
                new_neg = bool(new_words & NEGATION_WORDS)
                new_aff = bool(new_words & AFFIRMATION_WORDS)
                for old_item in older:
                    if new_item["id"] == old_item["id"]:
                        continue
                    old_text = (old_item["title"] or old_item["content"] or "").lower()
                    if len(old_text) < 20:
                        continue
                    sim = text_similarity(new_text[:80], old_text[:80])
                    if sim < 0.4:
                        continue
                    old_words = set(old_text.split())
                    old_neg = bool(old_words & NEGATION_WORDS)
                    old_aff = bool(old_words & AFFIRMATION_WORDS)
                    # Contradiction: one negates what the other affirms
                    if (new_neg and old_aff) or (new_aff and old_neg):
                        conflicts.append({
                            "new_id": new_item["id"],
                            "old_id": old_item["id"],
                            "new_text": new_text[:100],
                            "old_text": old_text[:100],
                            "similarity": round(sim, 3),
                            "domain": new_item["domain"] or "general",
                            "table": table,
                            "detected_at": now.isoformat(),
                        })
        except Exception as e:
            log.debug("Conflict scan on %s failed: %s", table, e)

    # Persist conflicts
    if conflicts:
        _save_conflicts(conflicts)
        if verbose:
            print(f"  [CONFLICT] {len(conflicts)} contradictions detected")
            for c in conflicts[:3]:
                print(f"    NEW: {c['new_text'][:60]}")
                print(f"    OLD: {c['old_text'][:60]}")
                print(f"    sim={c['similarity']}, domain={c['domain']}")
    elif verbose:
        print("  [CONFLICT] No contradictions found")
    return {"status": "ok", "conflicts": len(conflicts)}


def _save_conflicts(new_conflicts: list):
    """Append conflicts to persistent log."""
    try:
        from pulse.core.paths import get_state_dir
        conflict_file = get_state_dir() / "knowledge_conflicts.json"
        conflict_file.parent.mkdir(parents=True, exist_ok=True)
        existing = []
        if conflict_file.exists():
            try:
                existing = json.loads(conflict_file.read_text(encoding="utf-8"))
            except Exception:
                existing = []
        existing.extend(new_conflicts)
        existing = existing[-200:]  # Keep last 200
        conflict_file.write_text(json.dumps(existing, indent=2), encoding="utf-8")
    except Exception as e:
        log.debug("Conflict save failed: %s", e)
