# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""Briefing formatting -- format brain search results as compact actionable output.

P27/P28 extensions (items 112, 120) delegated to briefing_ext.py.
Signal helpers in briefing_signals.py.
"""

try:
    from pulse.brain.brain_query.briefing_ext import (
        detect_negative_transfer,
        check_prospective_memory,
        check_low_confidence_warning,
        check_predictive_coding,
    )
except Exception:
    detect_negative_transfer = lambda query, hits: []
    check_prospective_memory = lambda query: []
    check_low_confidence_warning = lambda avg_conf, hits: []
    check_predictive_coding = lambda q, n, d='': []

try:
    from pulse.brain.brain_query.briefing_wm import (
        check_phonological_priming,
        check_wm_volatility,
        check_shared_context,
    )
except Exception:
    check_phonological_priming = lambda q: []
    check_wm_volatility = lambda: []
    check_shared_context = lambda: []

try:
    from pulse.brain.integrity.self_check import check_and_warn as _self_check_warn
except Exception:
    _self_check_warn = lambda text: ''

try:
    from pulse.brain.brain_query.query_search import (
        _find_refinable_items, _load_active_broadcasts,
        _get_recommended_sequences, _get_competence_lines,
    )
except Exception:
    _find_refinable_items = lambda hits: []
    _load_active_broadcasts = lambda: []
    _get_recommended_sequences = lambda q: []
    _get_competence_lines = lambda q: []

try:
    from pulse.brain.brain_search.search_scoring_ext import _organize_columns as _org_columns
except Exception: _org_columns = None
try:
    from pulse.brain.brain_search.near_miss_advisor import get_near_miss_warning as _get_nm_warning
except Exception: _get_nm_warning = None
try:
    from pulse.brain.workspace.workspace_integrator import integrate as _integrate
except Exception: _integrate = None

_HABITUATION_THRESHOLD = 3  # default threshold; overridden by briefing_signals import below
from pulse.brain.brain_query.briefing_signals import (
    _RECENT_QUALITY, _RECENT_QUERIES, _HABITUATION_THRESHOLD,
    _DANGER_WORDS, _check_somatic_veto, get_flexibility_warning,
    check_schema_violations, check_interference, render_standard_sections,
    adversarial_injection, surprise_detection, predictive_triage,
    cortical_columns_summary, render_predictions_and_warnings,
)
from pulse.brain.brain_query.briefing_sections import (
    apply_danger_boost, apply_relevance_filter, annotate_source_labels,
    get_graph_expansions, apply_habituation, _compute_ignition_threshold,
)


# Item 73: _render_items helper (dead code removed per Item 4 wire fix)
# def _render_items(items, system_mode='S1', trunc=80):
#     """S1: terse [:200]; S2: detailed [:300] with conf/src."""
#     try:
#         lines = []
#         for item in items:
#             t = (item.get('title') or item.get('content') or item.get('text') or '')
#             if system_mode == 'S2':
#                 c = round(item.get('confidence', 0.5), 2); s = item.get('agent', item.get('source', ''))
#                 lines.append(f'  - {t[:300]} (conf={c}, src={s})')
#             else: lines.append(f'  - {t[:200]}')
#         return lines
#     except Exception: return []


def format_briefing(query: str, results: dict, model_tier: str = "") -> str:
    """Format brain search results as compact actionable briefing."""
    hits = results.get('results', {})
    total = results.get('total_results', 0)

    try:
        from pulse.core.interoception import get_signals
        _load = get_signals().get('agent_load', 0)  # Cognitive load adaptation
        _max_items = 3 if _load > 5 else 8  # S1: _max_items = 3; S2: _max_items = 8
        _system_mode = 'S1' if _load > 5 else 'S2'
    except Exception:
        _max_items, _system_mode = 10, 'S2'

    # Tier-based context depth: premium models ingest more, fast gets terse
    if model_tier == "premium":
        _max_items, _system_mode = 15, 'S2'
    elif model_tier == "standard":
        _max_items, _system_mode = 8, 'S2'
    elif model_tier == "fast":
        _max_items, _system_mode = 3, 'S1'
    _trunc_override = {"premium": 200, "standard": 120, "fast": 80}.get(model_tier)

    _max_items = apply_habituation(query, _max_items, _RECENT_QUERIES, _HABITUATION_THRESHOLD)
    apply_danger_boost(query, hits, _DANGER_WORDS)

    elapsed = results.get('elapsed_ms', 0)

    _conf_floor = _compute_ignition_threshold()
    _safe_conf = lambda h: float(h.get('confidence', 0.0)) if isinstance(h.get('confidence'), (int, float)) else 0.0
    all_hits_flat = [h for src in hits.values() if isinstance(src, list) for h in src if _safe_conf(h) >= _conf_floor]

    # N59: relevance filter (see briefing_sections.apply_relevance_filter)
    all_hits_flat = apply_relevance_filter(query, all_hits_flat)

    # N58: Annotate each hit with source attribution (agent + relative timestamp)
    annotate_source_labels(all_hits_flat)

    # Graph expansion via SEMANTIC/CAUSAL edges
    _expansions = get_graph_expansions(query)

    try:
        avg_conf = sum(float(h.get('confidence', 0.0)) for h in all_hits_flat) / len(all_hits_flat) if all_hits_flat else 0.0
    except (TypeError, ValueError):
        avg_conf = 0.5

    low_conf_warning = check_low_confidence_warning(avg_conf, all_hits_flat)

    predictive_lines: list = []
    try:
        predictive_lines = check_predictive_coding(query, total)
    except Exception:
        pass

    near_miss_warning: list = []
    try:
        if _get_nm_warning is not None:
            _nm_domain = (all_hits_flat[0].get('domain', '') if all_hits_flat else '')
            _nm_msg = _get_nm_warning(query, domain=_nm_domain)
            if _nm_msg:
                near_miss_warning = [_nm_msg]
    except Exception:
        pass

    flexibility_warning = get_flexibility_warning()
    veto_lines = _check_somatic_veto(hits)
    prospective_lines = check_prospective_memory(query)

    if total == 0:
        ignorance_msg = '!! IGNORANCE: Brain has no reliable knowledge about this topic. Proceed with caution.'
        try:
            _broad57 = ' '.join(query.split()[:2])
            from pulse.brain.brain_search.search_engine import brain_search as _bs57
            _r57 = _bs57(_broad57, max_per_source=3)
            if _r57.get('total_results', 0) > 0:
                ignorance_msg += f"\n!! FAILED IGNITION: Broadened search found {_r57['total_results']} related items"
        except Exception:
            pass
        if veto_lines:
            return '\n'.join(veto_lines + [ignorance_msg])
        return ignorance_msg

    lines = []
    if _expansions:
        lines.append('  ~ EXPANDED: query enriched with ' + ', '.join(_expansions))
    lines.extend(low_conf_warning)
    if avg_conf < 0.3 and all_hits_flat:
        lines.append(f'!! FAILED IGNITION: low avg confidence ({avg_conf:.2f})')
    confirmed_hits = [h for h in all_hits_flat if h.get('_confirmed')]
    for h in confirmed_hits[:3]:
        text = (h.get('text') or h.get('title') or h.get('description', ''))[:100].strip()
        if text:
            # N58: add source attribution (agent + relative timestamp)
            _src_lbl = h.get('_source_label', '')
            _prefix = f'{_src_lbl} ' if _src_lbl else ''
            lines.append(f'  ✓ CONFIRMED: {_prefix}{text}')

    lines.extend(check_schema_violations(all_hits_flat))
    lines.extend(check_interference(all_hits_flat))

    if _integrate and total >= 3:
        try:
            synthesis = _integrate(results, query, fast_only=True)
            if synthesis:
                for s in synthesis[:3]:
                    lines.append(f'  !! SYNTHESIS: {s}')
        except Exception:
            pass

    lines.extend(render_predictions_and_warnings(hits))

    _trunc = _trunc_override if _trunc_override is not None else (80 if _system_mode == 'S1' else 120)
    lines.extend(render_standard_sections(hits, _trunc, _system_mode))
    lines.extend(cortical_columns_summary(results, _org_columns))
    lines.extend(_get_competence_lines(query))
    lines.extend(_get_recommended_sequences(query))
    lines.extend(_load_active_broadcasts())
    lines.extend(_find_refinable_items(hits))

    if avg_conf < 0.4 and all_hits_flat:
        lines.append('!! IGNORANCE: Brain has no reliable knowledge about this topic. Proceed with caution.')

    adversarial_injection(lines, all_hits_flat)
    surprise_detection(lines, results)
    predictive_triage(lines, all_hits_flat)
    lines.extend(detect_negative_transfer(query, hits))

    # Item 3: Expert adversarial counterexample injection
    try:
        from pulse.brain.metacognition.metamemory import get_metamemory; _meta3 = get_metamemory()
        for _d3 in list({h.get("domain","") for h in all_hits_flat if h.get("domain")})[:2]:
            if _meta3.get(_d3, {}).get("competence_level", "") == "expert":
                from pulse.core.brain_db import get_conn as _gc3; num_adversarial = 2
                for _r3 in _gc3().execute(
                    "SELECT content FROM failures WHERE domain=? ORDER BY confidence DESC LIMIT ?",
                    (_d3, num_adversarial)).fetchall():
                    lines.append(f"  !! ADVERSARIAL [{_d3}]: {_r3[0][:80]}")
    except Exception:
        pass

    try:
        from pulse.brain.memory.working_memory import _mark_broadcast as _mb8
        _bids8 = [h.get('id', '') for h in all_hits_flat[:_max_items] if h.get('id')]
        if _bids8:
            _mb8(_bids8)
    except Exception:
        pass

    try:
        _c40 = [h.get('confidence', 0.5) for s in results.get('results', {}).values() if isinstance(s, list) for h in s]
        _RECENT_QUALITY.append(sum(_c40) / max(len(_c40), 1))
        rq = list(_RECENT_QUALITY)
        if len(rq) >= 3 and all(rq[i] > rq[i + 1] for i in range(len(rq) - 1)):
            lines.append('!! ATTENTION DRIFT: Result quality declining across recent queries')
    except Exception:
        pass

    lines.extend(predictive_lines)
    lines.extend(check_phonological_priming(query))
    lines.extend(check_wm_volatility())
    lines.extend(check_shared_context())

    # Phase 7: Inject pending failures for within-session real-time learning
    try:
        from pulse.brain.pending_failures import read_pending_failures
        for pf in read_pending_failures(max_items=3):
            pf_text = pf.get("content", "")[:80]
            if pf_text:
                lines.append(f"  !! PENDING FAIL: {pf_text}")
    except Exception:
        pass

    try:
        lines = lines[:max(_max_items, 15)]
    except Exception:
        pass

    if not lines and not veto_lines:
        return ''

    query_display = query[:50].strip()
    header = f'[BRAIN] Knowledge for: {query_display}'
    footer = f'({total} results, {elapsed}ms)'
    try:
        from pulse.brain.brain_query.briefing_ext import check_response_inhibition as _cri153
        _ri = _cri153()
        if _ri:
            lines.extend(_ri)
    except Exception:
        pass

    body_lines = [header] + lines[:_max_items] + [footer]

    if near_miss_warning:
        body_lines = near_miss_warning + body_lines
    if veto_lines:
        body_lines = veto_lines + body_lines
    if prospective_lines:
        body_lines = prospective_lines + body_lines
    if flexibility_warning:
        body_lines = flexibility_warning + body_lines

    final_output = chr(10).join(body_lines)

    _sc_warn = _self_check_warn(final_output)
    if _sc_warn:
        final_output = _sc_warn + chr(10) + final_output
    return final_output
