#!/usr/bin/env python3
"""Extract camera positions (timestamp, x, y, z) from lingbot-map NPZ poses.
Usage: poses_to_csv.py <input.npz> [--start_iso 2026-05-05T08:34:01] [--fps 1.0] > output.csv
"""
import argparse, sys
import numpy as np
from datetime import datetime, timezone

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument('npz')
    ap.add_argument('--start_iso', default=None, help='ISO timestamp of frame 0 (e.g. 2026-05-05T08:34:01)')
    ap.add_argument('--fps', type=float, default=1.0, help='frames per second (default 1.0)')
    ap.add_argument('--label', default='', help='segment label for CSV col')
    args = ap.parse_args()
    
    data = np.load(args.npz, allow_pickle=True)
    keys = list(data.keys())
    # auto-detect poses key
    poses = None
    for k in ['poses', 'extrinsics', 'cam_poses', 'c2w']:
        if k in keys:
            poses = data[k]; break
    if poses is None:
        # take first 3D array
        for k in keys:
            arr = data[k]
            if arr.ndim == 3 and arr.shape[-2:] in [(3,4),(4,4)]:
                poses = arr; break
    if poses is None:
        sys.exit(f'No poses found in {args.npz} (keys: {keys})')
    
    # start timestamp
    if args.start_iso:
        try:
            t0 = datetime.fromisoformat(args.start_iso).replace(tzinfo=timezone.utc).timestamp()
        except Exception:
            t0 = 0.0
    elif 'start_ns' in keys:
        t0 = float(data['start_ns']) / 1e9
    else:
        t0 = 0.0
    
    fps = float(args.fps)
    if 'fps' in keys:
        try: fps = float(data['fps'])
        except: pass
    
    print('segment,frame_idx,timestamp_s,x,y,z')
    for i, P in enumerate(poses):
        if P.shape == (4,4):
            P = P[:3]
        R, t = P[:, :3], P[:, 3]
        # extrinsic = world→cam ; cam position world = -R^T t
        # but lingbot might save c2w directly; check determinant heuristic
        pos = -R.T @ t  # if extrinsic
        ts = t0 + i / fps
        print(f'{args.label},{i},{ts:.6f},{pos[0]:.6f},{pos[1]:.6f},{pos[2]:.6f}')

if __name__ == '__main__':
    main()
