// Copyright © 2025 The µcad authors <info@ucad.xyz>
// SPDX-License-Identifier: AGPL-3.0-or-later

//! Processed Model Info, generated by [`Processor`].

use bevy::{asset::uuid::Uuid, color::Color, reflect::TypePath, transform::components::Transform};

use microcad_core::*;
use microcad_lang::{
    model::{Model, OutputType},
    render::ComputedHash,
    src_ref::{SrcRef, SrcReferrer},
};

use crate::{ToBevy, processor::registry};

/// Model info is a
#[derive(Clone, Default, TypePath)]
pub struct ModelInfo {
    /// The uuid of the model.
    pub model_uuid: Uuid,
    /// Geometry output uuid.
    pub geometry_output_uuid: Uuid,
    /// The original model hash.
    pub model_hash: u64,
    /// The output type for this model.
    pub output_type: OutputType,
    /// The transform for this model.
    pub transform: Transform,
    /// An optional color retrieved from a color attribute for this model.
    pub color: Option<Color>,
    /// The 2D bounds of this model.
    pub bounds_2d: Bounds2D,
    /// The 3D bounds of this model.
    pub bounds_3d: Bounds3D,
    /// The bounding sphere radius of this model.
    pub bounding_sphere_radius: Length,
    /// The radius of the ground circle.
    pub ground_radius: Length,
    /// A src code reference for this model.
    pub src_ref: SrcRef,
}

impl ModelInfo {
    /// Create model info from a model.
    pub fn from_model(model: &Model) -> Self {
        let model_ = model.borrow();
        let output = model_.output();

        Self {
            model_uuid: registry::generate_model_uuid(model),
            model_hash: model.computed_hash(),
            geometry_output_uuid: registry::generate_model_geometry_output_uuid(model),
            output_type: model.render_output_type(),
            transform: output.world_matrix.expect("Some matrix").to_bevy(),
            color: output.attributes.get_color().map(|c| c.to_bevy()),
            bounds_2d: output.calc_bounds_2d(),
            bounds_3d: output.calc_bounds_3d(),
            bounding_sphere_radius: output.scene_radius(),
            ground_radius: output.ground_radius(),
            src_ref: model.src_ref(),
        }
    }
}
