#pragma once
#include <string>
#include <vector>
#include "geometry/ConnectionPoint.h"

namespace MC {

// ── Track series / manufacturer ──────────────────────────────────────────────
enum class TrackSeries {
    MarlinC,    // Märklin C-Track  HO 1:87
    MarlinK,    // Märklin K-Track  HO 1:87
    MarlinZ,    // Märklin Z-Track  Z  1:220
    TrixC,      // TRIX C-Track     HO 1:87
    RokuhanZ,   // Rokuhan          Z  1:220
    Minitrix,   // Minitrix         N  1:160
    KatoN,      // Kato             N  1:160
    Gauge1,     // Märklin Gauge 1  I  1:32
    MarlinM,    // Märklin M-Track  HO 1:87  (vintage tinplate, discontinued)
};

// ── Piece category ────────────────────────────────────────────────────────────
enum class PieceType {
    Straight,
    Curve,
    TurnoutLeft,
    TurnoutRight,
    TurnoutY,          // symmetric Y
    DoubleCrossover,
    Bumper,            // end-of-track buffer
    Uncoupler,
    Crossing,          // fixed crossing (non-switching)
    FlexTrack,         // variable-length straight
    Turntable,         // rotating deck with spoke connections
    TurnoutCurved,     // curved turnout: stub + two parallel curve branches same direction
};

// ── A single entry in the track catalog ──────────────────────────────────────
struct TrackPiece {
    // Identity
    std::string catalogNumber;   // e.g. "24188", "24630"
    std::string displayName;     // e.g. "Straight 188.3mm"
    TrackSeries series;
    PieceType   type;

    // Geometry (real-world)
    double lengthMm  = 0.0;  // straight length or chord length for curves
    double radiusMm  = 0.0;  // 0 for straights
    double angleDeg  = 0.0;  // 0 for straights; sweep angle for curves/turnouts

    // Connection points in piece-local coordinates
    // Straight: index 0 = entry (west end), index 1 = exit (east end)
    // Curve:    index 0 = entry, index 1 = exit at angleDeg
    // Turnout:  index 0 = entry, index 1 = straight exit, index 2 = curved exit
    // DCrossing:index 0-3 clockwise from top-left
    std::vector<ConnectionPoint> connections;

    // Grid hint — how many cells this piece typically occupies
    // Used for plan.xml export quantization hint
    int gridW = 1;
    int gridH = 1;

    // Rendering hint
    bool   isMirrored = false;
    bool   isBridge   = false;
    bool   pairPiece  = false;  // always placed in pairs (e.g. 74618, 8976)
    bool   isRamp     = false;  // bridge ramp — can participate in grade chains

    // Optional per-connection series constraint (empty = no constraint)
    // If set, connection[i] will only snap to pieces of connSeries[i]
    std::vector<TrackSeries> connSeries;

    std::string seriesName() const {
        switch (series) {
            case TrackSeries::MarlinC:  return "Märklin C";
            case TrackSeries::MarlinK:  return "Märklin K";
            case TrackSeries::MarlinZ:  return "Märklin Z";
            case TrackSeries::TrixC:    return "TRIX C";
            case TrackSeries::RokuhanZ: return "Rokuhan Z";
            case TrackSeries::Minitrix: return "Minitrix N";
            case TrackSeries::KatoN:    return "Kato N";
            case TrackSeries::Gauge1:   return "Märklin Gauge 1";
            case TrackSeries::MarlinM:  return "Märklin M-Track";
        }
        return "Unknown";
    }
};

} // namespace MC
