#!/usr/bin/env python3
"""Emit the next daily fragment/layer for Robert Anton Wilson — Quantum Psychology.

Phase 1: first pass through source fragments.
Phase 2: deeper thematic layers after the first pass is complete.
"""
import argparse
import json
import re
from pathlib import Path
from datetime import datetime, timezone

PROJECT = Path('/home/spazio/quantum_psychology_wilson')
MANIFEST = PROJECT / 'manifest.json'
STATE = PROJECT / 'state.json'
FULL_TEXT = PROJECT / 'text' / 'book_full.txt'

LAYER_PLAN = [
    {
        'number': 1,
        'title': 'Нервная система как создатель реальности',
        'focus': 'Как восприятие становится активной интерпретацией сигналов; почему «реальность» проходит через тело, органы чувств, технологии и язык.',
        'keywords': ['нервная система', 'восприятие', 'активная интерпретация', 'экзистенциальная реальность', 'наблюдатель', 'органы чувств', 'инструменты'],
        'science_queries': [
            'predictive processing perception brain review',
            'active inference perception Karl Friston review',
            'embodied cognition perception neuroscience review',
            'Bayesian brain perception review'
        ],
        'cosmos_lens': 'Human OS, тело как прибор восприятия, смысловая сборка, состояние как фильтр реальности.'
    },
    {
        'number': 2,
        'title': 'Туннели реальности и Human OS',
        'focus': 'Как импринты, обучение, культура и повторяющиеся интерпретации создают персональный туннель реальности.',
        'keywords': ['туннель реальности', 'реальность-туннель', 'импринт', 'кондиционирование', 'обучение', 'программа', 'мозг', 'программное обеспечение'],
        'science_queries': [
            'schema theory perception cognition review',
            'cognitive biases reality perception review',
            'belief updating predictive processing review',
            'neuroplasticity learning environment review'
        ],
        'cosmos_lens': 'Внутренние программы, сценарные роли, карты мира, пересборка через вопросы/тело/микроопыт.'
    },
    {
        'number': 3,
        'title': 'Язык как магический интерфейс и ловушка',
        'focus': 'Как слова фиксируют идентичность, создают абстрактных “призраков”, сужают или раскрывают вероятность.',
        'keywords': ['язык', 'слова', 'абстракц', 'ярлык', 'символ', 'семантический', 'операционализм', 'эв-прайм', 'E-Prime'],
        'science_queries': [
            'language shapes thought linguistic relativity evidence review',
            'self-talk emotion regulation study review',
            'labeling emotions affect regulation neuroscience',
            'psychological distancing language self talk research'
        ],
        'cosmos_lens': 'Hacking Statement, смысловые формулы, вероятностный язык, выход из фраз-приговоров.'
    },
    {
        'number': 4,
        'title': 'Семантический шум: где событие превращается в историю',
        'focus': 'Как нервная система добавляет память, страх, ожидания и прошлые роли к текущему сигналу.',
        'keywords': ['шум', 'сигнал', 'семантический', 'интерпретация', 'категория', 'иллюзия', 'галлюцинац', 'проекция'],
        'science_queries': [
            'top-down processing perception ambiguity review',
            'emotion affects perception threat bias study',
            'memory reconsolidation perception current experience review',
            'affective forecasting interpretation bias research'
        ],
        'cosmos_lens': 'Чистый канал восприятия, пауза между сигналом и переводом, тело как детектор старого шума.'
    },
    {
        'number': 5,
        'title': 'Импринт, кондиционирование и телесная запись опыта',
        'focus': 'Почему часть “личности” может быть старой нервной настройкой, а не сущностью человека.',
        'keywords': ['импринт', 'кондиционирование', 'обучение', 'тело', 'эмоци', 'реакция', 'программа', 'контур'],
        'science_queries': [
            'critical periods imprinting learning neuroscience review',
            'conditioning fear learning amygdala review',
            'somatic markers decision making Damasio review',
            'trauma body memory nervous system review'
        ],
        'cosmos_lens': 'Где “я такая” становится записью тела; пересборка через безопасный новый опыт.'
    },
    {
        'number': 6,
        'title': 'Множественные “я” и контуры сознания',
        'focus': 'Как разные внутренние системы — выживание, эмоции, социальная роль, интеллект, тело, поле — создают разные версии мира.',
        'keywords': ['контур', 'восемь', 'я', 'личность', 'модель', 'нервн', 'мозг', 'сознание'],
        'science_queries': [
            'multiple self models cognitive neuroscience review',
            'default mode network self referential processing review',
            'polyvagal theory review social engagement nervous system',
            'ego states transactional analysis research review'
        ],
        'cosmos_lens': 'Карта внутренних операционных систем; какой контур сейчас измеряет деньги/любовь/проявление.'
    },
    {
        'number': 7,
        'title': 'Квантовая метафора: наблюдатель, вероятность и выбор',
        'focus': 'Где квантовая физика у Уилсона является строгой эпистемологической метафорой для восприятия, а где важно не делать псевдонаучных скачков.',
        'keywords': ['квант', 'наблюдатель', 'вероятност', 'измерен', 'частиц', 'волна', 'копенгаген', 'неопредел'],
        'science_queries': [
            'observer effect quantum mechanics measurement problem review',
            'quantum cognition probability decision making review',
            'Bayesian decision making uncertainty neuroscience review',
            'uncertainty tolerance cognitive flexibility research'
        ],
        'cosmos_lens': 'Линии вероятности как язык выбора и восприятия без обещаний “квантового манифестинга”.'
    },
    {
        'number': 8,
        'title': 'Социальные реальности и правила игры',
        'focus': 'Как культура, рынок, семья, профессия и духовные среды создают “очевидности”, которые человек принимает за устройство мира.',
        'keywords': ['социальн', 'реальность', 'игра', 'правила', 'культура', 'эмическ', 'этическ', 'общество'],
        'science_queries': [
            'social construction of reality psychology review',
            'cultural cognition risk perception research',
            'social identity theory perception intergroup review',
            'norms behavior decision making psychology review'
        ],
        'cosmos_lens': 'Правила игры денег, женственности, экспертности, духовности; выход из чужой эмической реальности.'
    },
    {
        'number': 9,
        'title': 'Операционализм: как вернуть подвижность внутренним приговорам',
        'focus': 'Как уточнение условий — кто, чем, когда, в каком состоянии измеряет — превращает приговор в эксперимент.',
        'keywords': ['операционализм', 'измер', 'инструмент', 'услов', 'прагматизм', 'эксперимент', 'провер'],
        'science_queries': [
            'operationalization psychology measurement validity review',
            'cognitive behavioral therapy cognitive restructuring evidence review',
            'implementation intentions behavior change meta analysis',
            'self experimentation n-of-1 behavior change research'
        ],
        'cosmos_lens': 'Операциональный перевод фраз “я не могу”, “деньги не идут”, “меня не выбирают”.'
    },
    {
        'number': 10,
        'title': 'Психосоматическое единство: мысль, эмоция, тело и выбор',
        'focus': 'Как идея становится телесным состоянием, а телесное состояние становится способом думать и выбирать.',
        'keywords': ['психосомат', 'тело', 'эмоци', 'мысл', 'состояние', 'нервная система', 'ощущ'],
        'science_queries': [
            'interoception emotion self awareness review',
            'embodied emotion cognition review',
            'somatic marker hypothesis decision making review',
            'heart rate variability emotion regulation review'
        ],
        'cosmos_lens': 'Тело как часть смысловой сборки; Audio Boost/какао/сессия как смена телесной проводимости.'
    },
    {
        'number': 11,
        'title': 'Прагматизм: истина как работающий инструмент',
        'focus': 'Как перестать поклоняться “правильной идее” и начать проверять, что даёт больше жизни, выбора, действия и результата.',
        'keywords': ['прагматизм', 'работает', 'истина', 'идея', 'практик', 'провер', 'результат', 'инструмент'],
        'science_queries': [
            'pragmatism psychology behavior change review',
            'acceptance commitment therapy values action evidence review',
            'experimental mindset behavior change research',
            'growth mindset intervention meta analysis'
        ],
        'cosmos_lens': 'Контент, офферы, цены, практики и смыслы как инструменты, которые тестируются жизнью.'
    },
    {
        'number': 12,
        'title': 'Cosmos Luminosity-сборка: методичка по смене туннеля реальности',
        'focus': 'Собрать из книги практическую методологию: диагностика туннеля, смена языка, тело, новые правила игры, микроэксперименты, интеграция.',
        'keywords': ['реальность', 'туннель', 'язык', 'тело', 'инструмент', 'измер', 'смысл', 'состояние', 'наблюдатель'],
        'science_queries': [
            'cognitive flexibility interventions review',
            'meaning making psychology wellbeing review',
            'narrative identity therapy review',
            'mindfulness decentering cognitive reappraisal research'
        ],
        'cosmos_lens': 'Готовая мини-методичка Hacking Foundation / Human OS по пересборке реальности.'
    },
]


def split_paragraphs(text: str):
    raw = re.split(r'\n\s*\n+', text)
    return [p.strip() for p in raw if len(p.strip()) > 80]


def collect_excerpts(text: str, keywords, max_chars=22000):
    paragraphs = split_paragraphs(text)
    selected = []
    seen = set()
    lower_keywords = [k.lower() for k in keywords]
    for p in paragraphs:
        low = p.lower()
        score = sum(1 for k in lower_keywords if k in low)
        if score and p not in seen:
            selected.append((score, p))
            seen.add(p)
    selected.sort(key=lambda x: (-x[0], len(x[1])))
    out = []
    total = 0
    for score, p in selected:
        block = p[:2500]
        if total + len(block) > max_chars:
            continue
        out.append(block)
        total += len(block) + 2
        if total >= max_chars * 0.85:
            break
    # fallback if keywords miss
    if not out:
        out = paragraphs[:8]
    return '\n\n---\n\n'.join(out)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--peek', action='store_true', help='Do not advance state')
    args = parser.parse_args()

    manifest = json.loads(MANIFEST.read_text(encoding='utf-8'))
    if STATE.exists():
        state = json.loads(STATE.read_text(encoding='utf-8'))
    else:
        state = {'next_fragment': 1}

    next_fragment = int(state.get('next_fragment', 1))
    total = int(manifest['total_fragments'])

    # Phase 1: original fragment pass
    if next_fragment <= total:
        frag = manifest['fragments'][next_fragment - 1]
        fragment_path = Path(frag['path'])
        fragment_text = fragment_path.read_text(encoding='utf-8')
        output_path = PROJECT / 'daily_outputs' / f"quantum_psychology_day_{next_fragment:03d}.md"

        payload = {
            'status': 'ok',
            'phase': 'first_pass_fragment',
            'book': manifest['book'],
            'fragment_number': next_fragment,
            'total_fragments': total,
            'fragment_title': frag['title'],
            'fragment_chars': frag['chars'],
            'fragment_path': str(fragment_path),
            'output_path': str(output_path),
            'accumulating_file': str(PROJECT / 'TOOLS_AND_INSIGHTS.md'),
            'project_dir': str(PROJECT),
            'generated_at_utc': datetime.now(timezone.utc).isoformat(),
            'fragment_text': fragment_text,
        }

        if not args.peek:
            state['next_fragment'] = next_fragment + 1
            state['last_fragment'] = next_fragment
            state['last_run_utc'] = payload['generated_at_utc']
            STATE.write_text(json.dumps(state, ensure_ascii=False, indent=2), encoding='utf-8')

        print(json.dumps(payload, ensure_ascii=False))
        return

    # Phase 2: deeper thematic layers
    next_layer = int(state.get('next_layer', 1))
    total_layers = len(LAYER_PLAN)
    if next_layer > total_layers:
        print(json.dumps({
            'status': 'done',
            'phase': 'deep_layers_complete',
            'book': manifest['book'],
            'message': 'Все тематические слои второго прохода уже разобраны.',
            'total_fragments': total,
            'total_layers': total_layers,
            'project_dir': str(PROJECT),
            'accumulating_file': str(PROJECT / 'TOOLS_AND_INSIGHTS.md'),
        }, ensure_ascii=False))
        return

    layer = LAYER_PLAN[next_layer - 1]
    full_text = FULL_TEXT.read_text(encoding='utf-8')
    excerpts = collect_excerpts(full_text, layer['keywords'])
    output_path = PROJECT / 'daily_outputs' / f"quantum_psychology_layer_{next_layer:03d}.md"

    payload = {
        'status': 'ok',
        'phase': 'deep_thematic_layer',
        'book': manifest['book'],
        'layer_number': next_layer,
        'total_layers': total_layers,
        'layer_title': layer['title'],
        'layer_focus': layer['focus'],
        'keywords': layer['keywords'],
        'science_queries': layer['science_queries'],
        'cosmos_lens': layer['cosmos_lens'],
        'source_excerpts_note': 'Use these excerpts for close reading. Quote only short fragments from the copyrighted book; paraphrase the rest transformatively.',
        'source_excerpts': excerpts,
        'full_text_path': str(FULL_TEXT),
        'output_path': str(output_path),
        'accumulating_file': str(PROJECT / 'TOOLS_AND_INSIGHTS.md'),
        'project_dir': str(PROJECT),
        'generated_at_utc': datetime.now(timezone.utc).isoformat(),
    }

    if not args.peek:
        state['next_layer'] = next_layer + 1
        state['last_layer'] = next_layer
        state['last_run_utc'] = payload['generated_at_utc']
        STATE.write_text(json.dumps(state, ensure_ascii=False, indent=2), encoding='utf-8')

    print(json.dumps(payload, ensure_ascii=False))


if __name__ == '__main__':
    main()
