"""Built-in rotary-kiln generator for the generic Scene Recipe compiler."""

from __future__ import annotations

import math
from typing import Any


def build_rotary_kiln(
    builder: Any,
    root: Any,
    prefix: str,
    parameters: dict[str, Any],
) -> None:
    length = float(parameters["length_m"])
    diameter = float(parameters["outer_diameter_m"])
    radius = diameter / 2
    slope_angle = math.degrees(math.atan(float(parameters["slope_percent"]) / 100))
    stations = int(parameters["support_stations"])
    shell = builder.generated_material(prefix + "_shell", "#707780", 0.65, 0.3)
    metal = builder.generated_material(prefix + "_metal", "#303840", 0.8, 0.22)
    lining = builder.generated_material(prefix + "_lining", "#B56A3B", 0.0, 0.75)
    concrete = builder.generated_material(prefix + "_concrete", "#8D9398", 0.0, 0.9)
    material = builder.generated_material(prefix + "_bed", "#D35B26", 0.0, 0.8)

    builder.add_generated_geometry(
        prefix + "_shell_body",
        {"type": "cylinder", "radius": radius, "depth": length, "vertices": 96},
        parent=root,
        material=shell,
        rotation_deg=(0, 90 + slope_angle, 0),
    )
    builder.add_generated_geometry(
        prefix + "_lining_body",
        {
            "type": "cylinder",
            "radius": max(0.05, radius - float(parameters["shell_thickness_m"])),
            "depth": length * 0.995,
            "vertices": 96,
        },
        parent=root,
        material=lining,
        rotation_deg=(0, 90 + slope_angle, 0),
    )
    if parameters.get("material_bed", True):
        builder.add_generated_geometry(
            prefix + "_material_bed",
            {
                "type": "cylinder",
                "radius": max(
                    0.03,
                    radius
                    - float(parameters["shell_thickness_m"])
                    - float(parameters["lining_thickness_m"]),
                ),
                "depth": length * 0.97,
                "vertices": 64,
            },
            parent=root,
            material=material,
            position=(0, 0, -radius * 0.25),
            rotation_deg=(0, 90 + slope_angle, 0),
        )

    usable = length * 0.7
    for index in range(stations):
        x = -usable / 2 + usable * index / (stations - 1)
        z = -x * math.tan(math.radians(slope_angle))
        builder.add_generated_geometry(
            f"{prefix}_tyre_{index + 1:02d}",
            {
                "type": "torus",
                "major_radius": radius + diameter * 0.035,
                "minor_radius": max(0.04, diameter * 0.055),
                "major_segments": 64,
                "minor_segments": 16,
            },
            parent=root,
            material=metal,
            position=(x, 0, z),
            rotation_deg=(0, 90 + slope_angle, 0),
        )
        builder.add_generated_geometry(
            f"{prefix}_foundation_{index + 1:02d}",
            {"type": "box", "size": [diameter * 0.7, diameter * 1.8, radius * 0.8]},
            parent=root,
            material=concrete,
            position=(x, 0, z - radius * 1.25),
        )

    if parameters.get("drive_system", True):
        builder.add_generated_geometry(
            prefix + "_girth_gear",
            {
                "type": "torus",
                "major_radius": radius + diameter * 0.08,
                "minor_radius": max(0.05, diameter * 0.07),
                "major_segments": 72,
                "minor_segments": 16,
            },
            parent=root,
            material=metal,
            position=(-length * 0.18, 0, length * 0.18 * math.tan(math.radians(slope_angle))),
            rotation_deg=(0, 90 + slope_angle, 0),
        )
        builder.add_generated_geometry(
            prefix + "_drive_motor",
            {"type": "box", "size": [diameter * 0.55, diameter * 0.4, diameter * 0.4]},
            parent=root,
            material=metal,
            position=(-length * 0.18, -radius * 1.45, -radius * 0.7),
        )

    if parameters.get("hoods", True):
        for name, x in (("tail_hood", -length * 0.54), ("head_hood", length * 0.54)):
            builder.add_generated_geometry(
                prefix + "_" + name,
                {"type": "box", "size": [diameter * 0.65, diameter * 1.4, diameter * 1.55]},
                parent=root,
                material=metal,
                position=(x, 0, -x * math.tan(math.radians(slope_angle))),
            )
    if parameters.get("burner", True):
        builder.add_generated_geometry(
            prefix + "_burner",
            {"type": "cylinder", "radius": max(0.03, diameter * 0.055), "depth": diameter * 2.2, "vertices": 32},
            parent=root,
            material=metal,
            position=(length * 0.57, 0, -length * 0.57 * math.tan(math.radians(slope_angle))),
            rotation_deg=(0, 90 + slope_angle, 0),
        )
    if parameters.get("inspection_platform", True):
        builder.add_generated_geometry(
            prefix + "_inspection_platform",
            {"type": "box", "size": [diameter * 1.6, diameter * 0.9, 0.12]},
            parent=root,
            material=metal,
            position=(length * 0.35, -radius * 1.2, -radius * 0.2),
        )
