// TCX → GPX. Parses Garmin Training Center XML and emits a GPX 1.1 file.

window.TOOL_HANDLERS['tcx-to-gpx'] = function TcxToGpxTool() {
  const G = window.MMGpx;
  const S = window.MMSports;
  const [filename, setFilename] = React.useState('');
  const [tracks, setTracks] = React.useState(null);
  const [error, setError] = React.useState('');

  const parseTCX = (text) => {
    const doc = new DOMParser().parseFromString(text, 'application/xml');
    if (doc.getElementsByTagName('parsererror').length) throw new Error('Invalid TCX file');
    const all = [];
    const trackpts = doc.getElementsByTagName('Trackpoint');
    let segment = [];
    for (const tp of trackpts) {
      const pos = tp.getElementsByTagName('Position')[0];
      const lat = Number(pos?.getElementsByTagName('LatitudeDegrees')[0]?.textContent);
      const lon = Number(pos?.getElementsByTagName('LongitudeDegrees')[0]?.textContent);
      const ele = Number(tp.getElementsByTagName('AltitudeMeters')[0]?.textContent || NaN);
      const time = tp.getElementsByTagName('Time')[0]?.textContent || null;
      if (Number.isFinite(lat) && Number.isFinite(lon)) {
        segment.push({ lat, lon, ele: Number.isFinite(ele) ? ele : null, time });
      }
    }
    if (segment.length) all.push({ name: 'Activity', segments: [segment] });
    if (!all.length) throw new Error('No GPS-bearing trackpoints found in this TCX file.');
    return all;
  };

  const onFile = async (f) => {
    if (!f) return;
    setError('');
    try {
      const text = await f.text();
      const parsed = parseTCX(text);
      setTracks(parsed); setFilename(f.name);
    } catch (e) { setError(e.message); setTracks(null); }
  };

  const download = () => {
    if (!tracks) return;
    const xml = G.buildGPX(tracks);
    const blob = new Blob([xml], { type: 'application/gpx+xml' });
    window.downloadBlob(blob, (filename.replace(/\.tcx$/i, '') || 'activity') + '.gpx');
  };

  if (!tracks) {
    return (
      <div className="mini-tool sport-tool">
        <S.SportsToolHeader title="TCX → GPX" sub="Convert Garmin Training Center XML to a GPX file." icon="swap" accent="#2563eb" />
        {error && <div style={{ marginBottom: 12 }}><window.ToolError error={error} onRetry={() => setError('')} /></div>}
        <window.Dropzone onFile={onFile} title="Drop a .tcx file" hint="Garmin / SportTracks export" accept=".tcx,application/xml" />
      </div>
    );
  }

  const points = G.flattenPoints(tracks);
  const stats = G.computeStats(points);

  return (
    <div className="mini-tool sport-tool">
      <S.SportsToolHeader title="TCX → GPX" sub={filename} icon="swap" accent="#2563eb" />
      <G.GpxMap points={points} height={260} title="Converted route" />
      <div className="gpx-stats">
        <G.StatTile label="Distance" value={`${(stats.distanceM / 1000).toFixed(2)} km`} />
        <G.StatTile label="Points" value={points.length.toLocaleString()} />
        {stats.gainM > 0 && <G.StatTile label="Elev gain" value={`${stats.gainM.toFixed(0)} m`} />}
      </div>
      <div className="cmp-actions">
        <button className="btn btn-secondary" onClick={() => setTracks(null)}>Another file</button>
        <button className="btn btn-primary" onClick={download}>
          <window.Icon name="download" size={16} /> Download .gpx
        </button>
      </div>
    </div>
  );
};
