import { describe, expect, it } from 'vitest';
import { parseGpxToTelemetryPoints, parseCsvToTelemetryPoints, synthesizeTelemetryTrack, generateRideGpx } from '../lib/telemetry-export';
import type { Ride } from '../components/app-cloud-data';
import { geographicSegments } from '../lib/telemetry-track';
// Sanitized MotorSignal bundle format; no production locations or account IDs.
export const recordedGpx = `
12180
25
`;
export const summaryRide = { id: 'ride_sanitized', startedAt: new Date('2026-09-03T20:00:00Z'), movingTime: 301,
distanceMiles: 15.66, topSpeedMph: 83.7, averageSpeed: 60, maxLeanLeft: 27, maxLeanRight: 26 } as Ride;
describe('recorded replay coordinates', () => {
it('never invents a route from summary metrics or a default start', () => {
expect(synthesizeTelemetryTrack(summaryRide).length).toBe(0);
});
it('preserves mixed attribute order, exact turns, chronological time and GPX segment breaks', () => {
const points = parseGpxToTelemetryPoints(recordedGpx);
expect(points.map(p => [p.latitude, p.longitude])).toEqual([[40,-74],[40.001,-73.999],[40.002,-73.998],[40.01,-73.99],[40.011,-73.989]]);
expect(points.map(p => (p as typeof p & { segmentId: number }).segmentId)).toEqual([0,0,0,1,1]);
expect(points[0].altitude).toBe(12);
expect(points[0].speed).toBe(18);
const exported = generateRideGpx(summaryRide, points);
expect(exported.match(//g)).toHaveLength(2);
});
it('preserves gaps from missing GPS CSV rows and invalid coordinates', () => {
const csv = 'timestamp,latitude,longitude,speed,leanAngle\n2026-09-03T20:00:00Z,0,0,18,0\n2026-09-03T20:00:01Z,,,18,0\n2026-09-03T20:00:02Z,0.002,0.003,18,0\n2026-09-03T20:00:03Z,91,0,18,0';
const points = parseCsvToTelemetryPoints(csv);
expect(points.map(p => [p.latitude,p.longitude])).toEqual([[0,0],[0.002,0.003]]);
expect((points[1] as typeof points[1] & { segmentId: number }).segmentId).toBe(1);
});
it('rejects missing/bad time instead of inventing current timestamps', () => {
expect(parseGpxToTelemetryPoints('')).toEqual([]);
});
it('passes exact latitude/longitude segments to the map without joining recording gaps',()=>{
const segments=geographicSegments(parseGpxToTelemetryPoints(recordedGpx));
expect(segments).toEqual([[[40,-74],[40.001,-73.999],[40.002,-73.998]],[[40.01,-73.99],[40.011,-73.989]]]);
const invalid=recordedGpx.replace('','');
expect(geographicSegments(parseGpxToTelemetryPoints(invalid)).map(s=>s.length)).toEqual([1,1,2]);
});
});