#!/usr/bin/env python3
"""Overthinking Detector - heuristic CLI (no external deps).

Usage: python3 overthinking_detector.py messages.jsonl
Input: one JSON object per line: {"id": "...", "text": "...", "ts": "..."}
Output: session report with a spiraling score and per-message flags.
"""
import json, re, sys
from collections import Counter
from difflib import SequenceMatcher

EMOTION = re.compile(r'\b(anxious|anxiety|worried|worry|stressed|stress|freaking|panicking|spiraling|overwhelmed|frustrated|angry|scared|afraid|unsure|confused|stuck|afraid)\b', re.I)
CIRCLE = re.compile(r'\b(again|still|repeating|circles|same (thing|issue|problem)|going in circles|rehash|loop)\b', re.I)
FILLER = re.compile(r'\b(maybe|perhaps|kind of|sort of|i think|not sure|probably|possibly)\b', re.I)

def norm(s):
    s = re.sub(r'[^a-z0-9 ]+', ' ', s.lower())
    return re.sub(r'\s+', ' ', s).strip()

def main(path):
    msgs = [json.loads(l) for l in open(path) if l.strip()]
    n = len(msgs)
    score = 0
    flags = []
    seen_topics = Counter()
    for i, m in enumerate(msgs):
        t = m.get('text','')
        nt = norm(t)
        tokens = set(re.findall(r'[a-z]{4,}', nt))
        f = []
        if EMOTION.search(t): f.append('emotional-language'); score += 1
        if CIRCLE.search(t): f.append('circling-language'); score += 2
        if FILLER.search(t): f.append('hedging/filler'); score += 0.5
        # near-duplicate check vs previous messages
        dup = None
        for j in range(max(0, i-8), i):
            prev = norm(msgs[j].get('text',''))
            if prev and SequenceMatcher(None, nt, prev).ratio() > 0.72:
                dup = msgs[j].get('id')
                break
        if dup:
            f.append('near-duplicate-of:%s' % dup); score += 2
        # repeated topic tokens
        rep = [tok for tok in tokens if seen_topics[tok] >= 2]
        if rep:
            f.append('repeated-topic:%s' % ','.join(sorted(rep)[:3])); score += 1
        for tok in tokens: seen_topics[tok] += 1
        if f:
            flags.append({'id': m.get('id'), 'flags': f, 'text': t[:140]})
    report = {
        'messages': n,
        'spiraling_score': round(score, 1),
        'verdict': 'high overthinking' if score >= 8 else ('moderate' if score >= 4 else 'low'),
        'top_repeated_topics': [w for w,c in seen_topics.most_common(10)],
        'flags': flags,
    }
    print(json.dumps(report, indent=2))

if __name__ == '__main__':
    main(sys.argv[1])
