// GPX Merger — combine multiple .gpx files into a single multi-track GPX.

window.TOOL_HANDLERS['gpx-merger'] = function GpxMergerTool() {
  const G = window.MMGpx;
  const S = window.MMSports;
  const [items, setItems] = React.useState([]);  // [{ name, tracks, points }]
  const [error, setError] = React.useState('');

  const addFiles = async (files) => {
    setError('');
    const next = [...items];
    for (const f of files) {
      try {
        const text = await f.text();
        const tracks = G.parseGPX(text);
        if (!tracks.length) throw new Error(`No tracks in ${f.name}`);
        const points = G.flattenPoints(tracks);
        next.push({ name: f.name, tracks, points });
      } catch (e) {
        setError(`${f.name}: ${e.message}`);
      }
    }
    setItems(next);
  };

  const remove = (i) => setItems(items.filter((_, idx) => idx !== i));
  const move = (i, dir) => {
    const next = [...items];
    const j = i + dir;
    if (j < 0 || j >= next.length) return;
    [next[i], next[j]] = [next[j], next[i]];
    setItems(next);
  };

  const merged = React.useMemo(() => {
    const allTracks = [];
    items.forEach((it, idx) => {
      it.tracks.forEach((t, ti) => {
        allTracks.push({
          name: `${it.name.replace(/\.gpx$/i, '')}${it.tracks.length > 1 ? ` · ${ti + 1}` : ''}`,
          segments: t.segments,
        });
      });
    });
    return allTracks;
  }, [items]);

  const allPoints = React.useMemo(() => items.flatMap((it) => it.points), [items]);
  const stats = G.computeStats(allPoints);

  const downloadMerged = () => {
    const xml = G.buildGPX(merged);
    const blob = new Blob([xml], { type: 'application/gpx+xml' });
    window.downloadBlob(blob, 'merged.gpx');
  };

  return (
    <div className="mini-tool sport-tool">
      <S.SportsToolHeader title="GPX Merger" sub="Stitch multiple tracks into one GPX file." icon="merge" accent="#16a34a" />

      <window.Dropzone onFile={addFiles} multiple
                       title={items.length ? 'Add more GPX files' : 'Drop one or more GPX files'}
                       hint=".gpx · order is preserved"
                       accept=".gpx" />
      {error && <div style={{ marginTop: 12 }}><window.ToolError error={error} onRetry={() => setError('')} /></div>}

      {items.length > 0 && (
        <>
          <div className="gpx-merge-list">
            {items.map((it, i) => (
              <div className="gpx-merge-row" key={i}>
                <div className="gmr-num">{i + 1}</div>
                <div className="gmr-name">{it.name}</div>
                <div className="gmr-stats">
                  {(G.computeStats(it.points).distanceM / 1000).toFixed(2)} km · {it.points.length} pts
                </div>
                <div className="gmr-actions">
                  <button className="icon-btn" disabled={i === 0} onClick={() => move(i, -1)} aria-label="Move up">↑</button>
                  <button className="icon-btn" disabled={i === items.length - 1} onClick={() => move(i, 1)} aria-label="Move down">↓</button>
                  <button className="icon-btn" onClick={() => remove(i)} aria-label="Remove"><window.Icon name="x" size={14} /></button>
                </div>
              </div>
            ))}
          </div>

          <div className="gpx-stats">
            <G.StatTile label="Tracks merged" value={merged.length} />
            <G.StatTile label="Total distance" value={`${(stats.distanceM / 1000).toFixed(2)} km`} />
            <G.StatTile label="Total elev gain" value={`${stats.gainM.toFixed(0)} m`} />
            <G.StatTile label="Total points" value={stats.pointCount.toLocaleString()} />
          </div>

          <G.GpxMap points={allPoints} height={300} title="Merged route preview" />

          <div className="cmp-actions">
            <button className="btn btn-secondary" onClick={() => setItems([])}>Clear all</button>
            <button className="btn btn-primary" onClick={downloadMerged}>
              <window.Icon name="download" size={16} /> Download merged GPX
            </button>
          </div>
        </>
      )}
    </div>
  );
};
