{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "mpmedia/step-processor/external-dimensional-diagram/v1",
  "title": "ExternalDimensionalDiagram",
  "description": "Schema for the external dimensional diagram sub-skill output. Designed for AI consumption, search indexing, and downstream documentation workflows (Odoo product data, CoWork, PDF assembly). All geometry values in millimeters. Imperial equivalents computed at export time.",

  "type": "object",
  "required": [
    "schema_version", "generated_at", "source_path", "model_name",
    "mode", "style", "engine_used", "units",
    "overall_width", "overall_height", "overall_depth",
    "bounding_box", "selected_parts", "excluded_parts",
    "layout", "outputs", "warnings", "notes"
  ],

  "properties": {

    "schema_version": {
      "type": "string",
      "const": "1.0",
      "description": "Schema version. Increment minor for additive changes, major for breaking changes."
    },

    "generated_at": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 UTC timestamp of generation run."
    },

    "source_path": {
      "type": "string",
      "description": "Absolute path to the source STEP file."
    },

    "model_name": {
      "type": "string",
      "description": "Human-readable product/model name. Sourced from datablock MD file if present, otherwise derived from filename stem."
    },

    "mode": {
      "type": "string",
      "enum": ["enclosure_only", "enclosure_plus_mounting", "mounting_only"],
      "description": "Geometry scope mode used for this run."
    },

    "style": {
      "type": "string",
      "enum": ["line_drawing", "rendered"],
      "description": "line_drawing = pure SVG wireframe/line art (MR28-style). rendered = rendered ISO views composited with dimensioned orthographic line views (MR16-style)."
    },

    "layout_mode": {
      "type": "string",
      "enum": ["single_sheet", "multi_page"],
      "description": "single_sheet = all views on one SVG/PDF sheet. multi_page = one view per page, used for large/complex models or when any single view would be too dense at standard scale. Auto-selected based on model bounding box and view count unless overridden."
    },

    "engine_used": {
      "type": "string",
      "enum": ["build123d", "freecad"],
      "description": "Geometry engine that successfully loaded and processed the file."
    },

    "fallback_invoked": {
      "type": "boolean",
      "description": "True if the primary engine (build123d) failed and the fallback was used."
    },

    "units": {
      "type": "object",
      "required": ["primary", "secondary"],
      "properties": {
        "primary": { "type": "string", "const": "mm" },
        "secondary": {
          "type": "string",
          "const": "in",
          "description": "Imperial inches shown in parentheses at reduced italic size where space allows."
        }
      }
    },

    "overall_width":  { "type": "number", "description": "Overall external width in mm (X axis)." },
    "overall_height": { "type": "number", "description": "Overall external height in mm (Z axis)." },
    "overall_depth":  { "type": "number", "description": "Overall external depth in mm (Y axis)." },

    "bounding_box": {
      "type": "object",
      "required": ["x_min", "x_max", "y_min", "y_max", "z_min", "z_max"],
      "properties": {
        "x_min": { "type": "number" },
        "x_max": { "type": "number" },
        "y_min": { "type": "number" },
        "y_max": { "type": "number" },
        "z_min": { "type": "number" },
        "z_max": { "type": "number" }
      }
    },

    "active_area": {
      "type": ["object", "null"],
      "description": "Detected front-face aperture or screen cutout. Null if not detectable.",
      "properties": {
        "width":    { "type": "number", "description": "mm" },
        "height":   { "type": "number", "description": "mm" },
        "diagonal": { "type": "number", "description": "mm" },
        "diagonal_inches": { "type": "number", "description": "Computed inches for display diagonal labeling." },
        "offset_left":   { "type": "number", "description": "mm from enclosure left edge" },
        "offset_top":    { "type": "number", "description": "mm from enclosure top edge" },
        "detection_confidence": {
          "type": "string",
          "enum": ["high", "medium", "low"],
          "description": "Confidence level of aperture detection."
        }
      }
    },

    "mounting_dimensions": {
      "type": ["object", "null"],
      "description": "Null if mode is enclosure_only or no mounting geometry detected.",
      "properties": {
        "pattern_type": {
          "type": "string",
          "enum": ["linear", "grid", "vesa", "custom", "unknown"],
          "description": "Detected mounting hole pattern type."
        },
        "vesa_standard": {
          "type": ["string", "null"],
          "description": "e.g. VESA 100x100, VESA 200x200. Null if not a standard VESA pattern."
        },
        "hole_diameter": { "type": "number", "description": "mm. Null if mixed diameters." },
        "hole_count": { "type": "integer" },
        "spacing_x": { "type": ["number", "null"], "description": "Center-to-center horizontal spacing in mm." },
        "spacing_y": { "type": ["number", "null"], "description": "Center-to-center vertical spacing in mm." },
        "spacing_chain_x": {
          "type": ["array", "null"],
          "items": { "type": "number" },
          "description": "Array of sequential horizontal spacings for chain dimensioning. e.g. [113, 200, 200, 200, 113]"
        },
        "spacing_chain_y": {
          "type": ["array", "null"],
          "items": { "type": "number" },
          "description": "Array of sequential vertical spacings for chain dimensioning."
        },
        "offset_from_left":   { "type": ["number", "null"] },
        "offset_from_top":    { "type": ["number", "null"] },
        "offset_from_right":  { "type": ["number", "null"] },
        "offset_from_bottom": { "type": ["number", "null"] }
      }
    },

    "mounting_variants": {
      "type": ["array", "null"],
      "description": "When the STEP file contains multiple mounting subassemblies (e.g. wall mount + ceiling mount + floor stand), each variant is listed here. Each can produce a separate diagram run.",
      "items": {
        "type": "object",
        "required": ["variant_name", "part_ids"],
        "properties": {
          "variant_name": {
            "type": "string",
            "description": "Human-readable variant label. e.g. 'Wall Mount - VESA 200x200'"
          },
          "part_ids": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Part names/IDs from the assembly tree included in this variant."
          },
          "diagram_output": {
            "type": ["string", "null"],
            "description": "Path to the generated diagram for this variant, if rendered."
          }
        }
      }
    },

    "selected_parts": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Part names included in the geometry scope for this run."
    },

    "excluded_parts": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Part names explicitly excluded (internal components, fasteners, etc.)."
    },

    "mapping_file_used": {
      "type": ["string", "null"],
      "description": "Path to the parts mapping JSON file used, if any."
    },

    "datablock": {
      "type": "object",
      "description": "Metadata shown in the diagram title/data block. Sourced from datablock MD file.",
      "properties": {
        "model_number":   { "type": "string" },
        "display_name":   { "type": "string" },
        "drawing_date":   { "type": "string", "format": "date" },
        "revision":       { "type": "string" },
        "drawn_by":       { "type": "string" },
        "company":        { "type": "string" },
        "units_note":     { "type": "string", "default": "Dimensions in mm (in)" },
        "scale":          { "type": "string", "default": "NTS" },
        "custom_fields":  {
          "type": "object",
          "additionalProperties": { "type": "string" },
          "description": "Any additional key-value pairs from the MD file to show in the data block."
        }
      }
    },

    "layout": {
      "type": "object",
      "description": "Describes the view layout used in the generated diagram.",
      "required": ["views_included", "sheet_size"],
      "properties": {
        "views_included": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": ["front", "rear", "left", "right", "top", "bottom", "isometric_front", "isometric_rear"]
          },
          "description": "Ordered list of views included in the diagram."
        },
        "sheet_size": {
          "type": "string",
          "enum": ["A4_landscape", "A4_portrait", "A3_landscape", "A3_portrait", "A2_landscape", "letter_landscape", "letter_portrait", "auto"],
          "description": "Sheet size used. 'auto' selects based on model aspect ratio and view count."
        },
        "scale_ratio": {
          "type": ["string", "null"],
          "description": "e.g. '1:5', '1:10', 'NTS' (not to scale). NTS used when views are schematic rather than precise scale."
        },
        "dimension_style": {
          "type": "string",
          "enum": ["chain", "ordinate", "baseline"],
          "description": "Dimensioning style used. chain = sequential (113-200-200-113). ordinate = from common datum. baseline = all from one edge."
        },
        "iso_style": {
          "type": "string",
          "enum": ["line_wireframe", "shaded_render", "none"],
          "description": "Isometric view rendering approach."
        }
      }
    },

    "outputs": {
      "type": "object",
      "description": "Paths to all generated output files.",
      "properties": {
        "diagram_png":   { "type": ["string", "null"] },
        "diagram_pdf":   { "type": ["string", "null"] },
        "diagram_svg":   { "type": ["string", "null"], "description": "Source SVG always retained alongside exports." },
        "iso_png":       { "type": ["string", "null"] },
        "front_png":     { "type": ["string", "null"] },
        "side_png":      { "type": ["string", "null"] },
        "rear_png":      { "type": ["string", "null"] },
        "meta_json":     { "type": "string", "description": "Path to this metadata JSON file." },
        "variant_outputs": {
          "type": ["array", "null"],
          "items": {
            "type": "object",
            "properties": {
              "variant_name": { "type": "string" },
              "diagram_png":  { "type": ["string", "null"] },
              "diagram_pdf":  { "type": ["string", "null"] },
              "meta_json":    { "type": ["string", "null"] }
            }
          }
        }
      }
    },

    "warnings": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Non-fatal issues encountered during generation. e.g. 'active area detection confidence: low', 'mounting holes not detected', 'fallback engine used'."
    },

    "notes": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Informational messages. e.g. 'Chinese part names translated', '3 mounting variants detected'."
    }
  }
}
