import 'dart:convert';

DrawRouting drawRoutingFromJson(String str) =>
    DrawRouting.fromJson(json.decode(str));

String drawRoutingToJson(DrawRouting data) => json.encode(data.toJson());

class DrawRouting {
  DrawRouting({
    required this.type,
    required this.features,
    required this.bbox,
    required this.metadata,
  });

  String type;
  List<Feature> features;
  List<double> bbox;
  Metadata metadata;

  factory DrawRouting.fromJson(Map<String, dynamic> json) {
    return DrawRouting(
      type: json["type"],
      features:
          List<Feature>.from(json["features"].map((x) => Feature.fromJson(x))),
      bbox: List<double>.from(json["bbox"].map((x) => x.toDouble())),
      metadata: Metadata.fromJson(json["metadata"]),
    );
  }

  Map<String, dynamic> toJson() => {
        "type": type,
        "features": List<dynamic>.from(features.map((x) => x.toJson())),
        "bbox": List<dynamic>.from(bbox.map((x) => x)),
        "metadata": metadata.toJson(),
      };
}

class Feature {
  Feature({
    required this.bbox,
    required this.type,
    required this.properties,
    required this.geometry,
  });

  List<num> bbox;
  String type;
  Properties properties;
  Geometry geometry;

  factory Feature.fromJson(Map<String, dynamic> json) => Feature(
        bbox: List<double>.from(json["bbox"].map((x) => x.toDouble())),
        type: json["type"],
        properties: Properties.fromJson(json["properties"]),
        geometry: Geometry.fromJson(json["geometry"]),
      );

  Map<String, dynamic> toJson() => {
        "bbox": List<dynamic>.from(bbox.map((x) => x)),
        "type": type,
        "properties": properties.toJson(),
        "geometry": geometry.toJson(),
      };
}

class Geometry {
  Geometry({
    required this.coordinates,
    required this.type,
  });

  List<List<double>> coordinates;
  String type;

  factory Geometry.fromJson(Map<String, dynamic> json) => Geometry(
        coordinates: List<List<double>>.from(json["coordinates"]
            .map((x) => List<double>.from(x.map((x) => x.toDouble())))),
        type: json["type"],
      );

  Map<String, dynamic> toJson() => {
        "coordinates": List<dynamic>.from(
            coordinates.map((x) => List<dynamic>.from(x.map((x) => x)))),
        "type": type,
      };
}

class Properties {
  Properties({
    required this.segments,
    required this.summary,
    required this.wayPoints,
  });

  List<Segment> segments;
  Summary summary;
  List<num> wayPoints;

  factory Properties.fromJson(Map<String, dynamic> json) => Properties(
        segments: List<Segment>.from(
            json["segments"].map((x) => Segment.fromJson(x))),
        summary: Summary.fromJson(json["summary"]),
        wayPoints: List<int>.from(json["way_points"].map((x) => x)),
      );

  Map<String, dynamic> toJson() => {
        "segments": List<dynamic>.from(segments.map((x) => x.toJson())),
        "summary": summary.toJson(),
        "way_points": List<dynamic>.from(wayPoints.map((x) => x)),
      };
}

class Segment {
  Segment({
    required this.distance,
    required this.duration,
    required this.steps,
  });

  num distance;
  num duration;
  List<Step> steps;

  factory Segment.fromJson(Map<String, dynamic> json) => Segment(
        distance: json["distance"].toDouble(),
        duration: json["duration"],
        steps: List<Step>.from(json["steps"].map((x) => Step.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "distance": distance,
        "duration": duration,
        "steps": List<dynamic>.from(steps.map((x) => x.toJson())),
      };
}

class Step {
  Step({
    required this.distance,
    required this.duration,
    required this.type,
    required this.instruction,
    required this.name,
    required this.wayPoints,
  });

  num distance;
  num duration;
  num type;
  String instruction;
  String name;
  List<num> wayPoints;

  factory Step.fromJson(Map<String, dynamic> json) => Step(
        distance: json["distance"].toDouble(),
        duration: json["duration"].toDouble(),
        type: json["type"],
        instruction: json["instruction"],
        name: json["name"],
        wayPoints: List<int>.from(json["way_points"].map((x) => x)),
      );

  Map<String, dynamic> toJson() => {
        "distance": distance,
        "duration": duration,
        "type": type,
        "instruction": instruction,
        "name": name,
        "way_points": List<dynamic>.from(wayPoints.map((x) => x)),
      };
}

class Summary {
  Summary({
    required this.distance,
    required this.duration,
  });

  num distance;
  num duration;

  factory Summary.fromJson(Map<String, dynamic> json) => Summary(
        distance: json["distance"].toDouble(),
        duration: json["duration"],
      );

  Map<String, dynamic> toJson() => {
        "distance": distance,
        "duration": duration,
      };
}

class Metadata {
  Metadata({
    required this.attribution,
    required this.service,
    required this.timestamp,
    required this.query,
    required this.engine,
  });

  String attribution;
  String service;
  num timestamp;
  Query query;
  Engine engine;

  factory Metadata.fromJson(Map<String, dynamic> json) => Metadata(
        attribution: json["attribution"],
        service: json["service"],
        timestamp: json["timestamp"],
        query: Query.fromJson(json["query"]),
        engine: Engine.fromJson(json["engine"]),
      );

  Map<String, dynamic> toJson() => {
        "attribution": attribution,
        "service": service,
        "timestamp": timestamp,
        "query": query.toJson(),
        "engine": engine.toJson(),
      };
}

class Engine {
  Engine({
    required this.version,
    required this.buildDate,
    required this.graphDate,
  });

  String version;
  DateTime buildDate;
  DateTime graphDate;

  factory Engine.fromJson(Map<String, dynamic> json) => Engine(
        version: json["version"],
        buildDate:
            DateTime.tryParse(json["build_date"])?.toLocal() ?? DateTime.now(),
        graphDate:
            DateTime.tryParse(json["graph_date"])?.toLocal() ?? DateTime.now(),
      );

  Map<String, dynamic> toJson() => {
        "version": version,
        "build_date": buildDate.toIso8601String(),
        "graph_date": graphDate.toIso8601String(),
      };
}

class Query {
  Query({
    required this.coordinates,
    required this.profile,
    required this.format,
  });

  List<List<num>> coordinates;
  String profile;
  String format;

  factory Query.fromJson(Map<String, dynamic> json) => Query(
        coordinates: List<List<double>>.from(json["coordinates"]
            .map((x) => List<double>.from(x.map((x) => x.toDouble())))),
        profile: json["profile"],
        format: json["format"],
      );

  Map<String, dynamic> toJson() => {
        "coordinates": List<dynamic>.from(
            coordinates.map((x) => List<dynamic>.from(x.map((x) => x)))),
        "profile": profile,
        "format": format,
      };
}
