import json
import math

# Load robot.json
with open(r'../../data/robot/robot.json') as f:
    robot = json.load(f)

# Extract markers by link
markers_by_link = {}
for link_name, link_data in robot['links'].items():
    markers = link_data.get('markers', [])
    if markers:
        markers_by_link[link_name] = markers

print("=" * 70)
print("MARKER DISTRIBUTION BY LINK")
print("=" * 70)
for link, markers in markers_by_link.items():
    print(f"\n{link}: {len(markers)} markers")
    for m in markers:
        pos = m['position']
        print(f"  ID {m['id']:3d}: pos={pos}")

# Check rigid body constraints: distances within each link
print("\n" + "=" * 70)
print("RIGID BODY CONSTRAINT CHECK (Arm1, Ellbow, Arm2)")
print("=" * 70)

for link_name in ['Arm1', 'Ellbow', 'Arm2']:
    if link_name not in markers_by_link:
        continue
    
    markers = markers_by_link[link_name]
    positions = [(m['position'][0], m['position'][1], m['position'][2]) for m in markers]
    
    print(f"\n{link_name}:")
    if len(positions) > 1:
        for i in range(len(positions)):
            for j in range(i+1, len(positions)):
                dx = positions[i][0] - positions[j][0]
                dy = positions[i][1] - positions[j][1]
                dz = positions[i][2] - positions[j][2]
                dist = math.sqrt(dx*dx + dy*dy + dz*dz)
                print(f"  Marker {markers[i]['id']:3d} <-> {markers[j]['id']:3d}: {dist:7.2f} mm")
    else:
        print(f"  Only {len(positions)} marker(s)")

# Check X-distances between links
print("\n" + "=" * 70)
print("X-POSITION CONSTRAINT CHECK (Link relationships)")
print("=" * 70)

# Get marker positions per link
link_x_positions = {}
for link_name in ['Board', 'Base', 'Arm1', 'Ellbow', 'Arm2']:
    if link_name in markers_by_link:
        x_vals = [m['position'][0] for m in markers_by_link[link_name]]
        link_x_positions[link_name] = {
            'min_x': min(x_vals),
            'max_x': max(x_vals),
            'count': len(x_vals)
        }

print("\nX-position ranges by link (local coords):")
for link, data in link_x_positions.items():
    print(f"  {link:10s}: x in [{data['min_x']:7.2f}, {data['max_x']:7.2f}] mm  ({data['count']} markers)")

# Check X-distance between Arm1 and Ellbow
print("\nKey constraint analysis:")
arm1_x = [m['position'][0] for m in markers_by_link['Arm1']]
ellbow_x = [m['position'][0] for m in markers_by_link['Ellbow']]
print(f"  Arm1 local X: {arm1_x}")
print(f"  Ellbow local X: {ellbow_x}")
print(f"  => BOTH rotate around X-axis, so X-spread within each link is FIXED")
print(f"  => X-distance between links is FIXED in world (different local X values)")

# Check Arm2 structure
print("\n" + "=" * 70)
print("ARM2 KINEMATIC CHECK (sin(a) dependency)")
print("=" * 70)

arm2_markers = markers_by_link['Arm2']
print(f"\nArm2 has {len(arm2_markers)} markers")
print("Arm2 marker positions (local coords, before 'a' rotation around Y):")
for m in arm2_markers:
    pos = m['position']
    print(f"  ID {m['id']:3d}: x={pos[0]:8.2f}, y={pos[1]:8.2f}, z={pos[2]:8.2f}")

print("\nWhen Arm2 rotates around Y-axis (variable 'a'):")
print("  Rotation matrix Ry(a) acts on [x_local, y_local, z_local]:")
print("  X_world = 90 + x_local * cos(a) - z_local * sin(a)")
print("  Y_world = y_local (unchanged)")
print("  Z_world = x_local * sin(a) + z_local * cos(a)")
print("\n=> X_world DEPENDS on sin(a) and z_local values!")

# Verify: X differences between Arm2 markers
arm2_x_vals = [m['position'][0] for m in arm2_markers]
arm2_z_vals = [m['position'][2] for m in arm2_markers]
print(f"\nArm2 local X values: {sorted(set(arm2_x_vals))}")
print(f"Arm2 local Z values: {sorted(set(arm2_z_vals))}")
if len(set(arm2_z_vals)) > 1:
    print(f"=> Multiple Z values present: X_world will differ by sin(a) contributions")

print("\n" + "=" * 70)
print("SUMMARY: WHICH CONSTRAINTS MAKE SENSE?")
print("=" * 70)
print("""
1. RIGID BODY DISTANCES within Arm1/Ellbow/Arm2:
   ✓ VALID - Fixed distances between markers on same rigid link
   ✓ HELPS with: Preventing deformation, reducing degrees of freedom
   
2. X-DISTANCES between links (Arm1, Ellbow, Base):
   ✓ VALID - Both rotate around X-axis, so relative X is fixed
   ✓ HELPS with: Preventing sliding along links
   
3. X-POSITION of Arm2 dependent on sin(a):
   ⚠ PARTIALLY VALID - Different markers have different dependencies
   ✓ HELPS with: Constraining the a variable from Z-spread observation
   
IMPLEMENTATION RECOMMENDATION:
- Start with constraints 1 & 2 (rigid body + inter-link X)
- Use constraint 3 as a sanity check on 'a' estimation
""")
