"""Analyze POI detection patterns from a project's auto frame data.

Reads the editor draft from the DB and prints per-block detection analysis:
- Sample count, primary subject trajectory
- Outlier detection (samples far from running median)
- Velocity/acceleration patterns
- Consistency score
"""
import os, sys, json, statistics
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'backend'))
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')

import django
django.setup()

from apps.editor.models import Project

PROJECT_ID = 25

project = Project.objects.get(id=PROJECT_ID)
draft = project.editor_draft
if not draft:
    print("No editor draft found"); sys.exit(1)

sequences = draft.get('sequences', [])
active_seq_id = draft.get('activeSequenceId')
seq = next((s for s in sequences if s.get('id') == active_seq_id), sequences[0] if sequences else None)
if not seq:
    print("No sequence found"); sys.exit(1)

print(f"Sequence: {seq.get('label', seq.get('id', '?'))[:80]}")
summary = seq.get('autoFrameSummary')
if not summary:
    print("No autoFrameSummary in this sequence"); sys.exit(1)

blocks = summary.get('blocks', [])
print(f"Blocks with data: {len(blocks)}\n")

for block in blocks:
    block_id = block.get('blockId', '?')
    label = block.get('label', '')[:50]
    detections = block.get('frame_detections', [])
    print(f"=== Block {block_id}: {label} ===")
    print(f"  Samples: {len(detections)}")
    
    if not detections:
        print("  (no detections)\n")
        continue
    
    # Extract primary subject per sample
    primaries = []
    for i, det in enumerate(detections):
        subjects = det.get('s', [])
        if not subjects:
            primaries.append(None)
            continue
        top = max(subjects, key=lambda s: s.get('score', 0))
        primaries.append({
            'i': i,
            't': det.get('t', 0),
            'cx': top.get('cx', 0.5),
            'cy': top.get('cy', 0.5),
            'score': top.get('score', 0),
            'n_subjects': len(subjects),
        })
    
    valid = [p for p in primaries if p is not None and p['score'] >= 0.25]
    if len(valid) < 2:
        print(f"  Valid samples (score>=0.25): {len(valid)} — too few\n")
        continue
    
    cx_values = [p['cx'] for p in valid]
    cy_values = [p['cy'] for p in valid]
    
    median_cx = statistics.median(cx_values)
    median_cy = statistics.median(cy_values)
    stdev_cx = statistics.stdev(cx_values) if len(cx_values) > 1 else 0
    stdev_cy = statistics.stdev(cy_values) if len(cy_values) > 1 else 0
    
    print(f"  Valid samples: {len(valid)}")
    print(f"  CX: median={median_cx:.3f}  stdev={stdev_cx:.3f}  range=[{min(cx_values):.3f}, {max(cx_values):.3f}]")
    print(f"  CY: median={median_cy:.3f}  stdev={stdev_cy:.3f}  range=[{min(cy_values):.3f}, {max(cy_values):.3f}]")
    
    # Identify outliers (>2 stdev from median or >0.12 absolute)
    outlier_threshold = max(2 * stdev_cx, 0.12)
    outliers = []
    for p in valid:
        dist = abs(p['cx'] - median_cx)
        if dist > outlier_threshold:
            outliers.append(p)
    
    print(f"  Outliers (>{outlier_threshold:.3f} from median CX): {len(outliers)}/{len(valid)}")
    for o in outliers:
        print(f"    sample {o['i']}: t={o['t']:.0f}ms  cx={o['cx']:.3f}  cy={o['cy']:.3f}  score={o['score']:.2f}  dist={abs(o['cx']-median_cx):.3f}")
    
    # Velocity analysis (cx change between consecutive samples)
    velocities = []
    for j in range(1, len(valid)):
        dt = max(valid[j]['t'] - valid[j-1]['t'], 1)
        dx = valid[j]['cx'] - valid[j-1]['cx']
        velocities.append({
            'from_i': valid[j-1]['i'],
            'to_i': valid[j]['i'],
            'dx': dx,
            'dt_ms': dt,
            'vel': dx / (dt / 1000) if dt > 0 else 0,  # units/sec
        })
    
    if velocities:
        vels = [abs(v['vel']) for v in velocities]
        print(f"  Velocity (|dx/dt| units/s): mean={statistics.mean(vels):.3f}  max={max(vels):.3f}")
        # Show the 3 biggest jumps
        biggest_jumps = sorted(velocities, key=lambda v: abs(v['vel']), reverse=True)[:3]
        for v in biggest_jumps:
            print(f"    jump {v['from_i']}->{v['to_i']}: dx={v['dx']:+.3f} in {v['dt_ms']}ms  vel={v['vel']:+.3f}/s")
    
    # Per-sample detail (compact)
    print(f"  --- Sample trajectory ---")
    for p in valid:
        marker = " ** OUTLIER" if p in outliers else ""
        print(f"    [{p['i']:2d}] t={p['t']:>7.0f}ms  cx={p['cx']:.3f}  cy={p['cy']:.3f}  score={p['score']:.2f}  subjects={p['n_subjects']}{marker}")
    
    print()

print("Done.")
