#![cfg(feature = "lod")]

use archetype_asset::cache::pool::AssetMemoryPool;
use archetype_asset::lod::{self, MeshSimplifier, MeshoptSimplifier};
use archetype_asset::model::{Mesh, PrimitiveType};
use archetype_asset::renderer::Vertex;
use std::sync::Arc;

fn create_dense_mesh(pool: &AssetMemoryPool) -> Mesh {
    // Create a 10x10 grid of quads (200 triangles)
    let size = 10;
    let mut vertices = Vec::new();
    let mut indices = Vec::new();

    for y in 0..=size {
        for x in 0..=size {
            vertices.push(Vertex {
                position: [x as f32, y as f32, 0.0],
                normal: [0.0, 0.0, 1.0],
                uv: [x as f32 / size as f32, y as f32 / size as f32],
                tangent: [1.0, 0.0, 0.0, 1.0],
                color: [1.0, 1.0, 1.0, 1.0],
            });
        }
    }

    for y in 0..size {
        for x in 0..size {
            let i = y * (size + 1) + x;
            let j = i + 1;
            let k = (y + 1) * (size + 1) + x;
            let l = k + 1;

            indices.extend_from_slice(&[i as u32, j as u32, k as u32]);
            indices.extend_from_slice(&[j as u32, l as u32, k as u32]);
        }
    }

    Mesh::new(
        Some("grid".to_string()),
        PrimitiveType::Triangles,
        vertices,
        indices,
        None,
        pool,
    )
}

#[test]
#[cfg(feature = "lod")]
fn test_lod_simplification() {
    let pool = AssetMemoryPool::new();
    let mesh = create_dense_mesh(&pool);
    let initial_verts = mesh.vertex_count();
    let initial_indices = mesh.index_count();

    println!(
        "Initial: {} verts, {} indices",
        initial_verts, initial_indices
    );

    let simplifier = MeshoptSimplifier::new(0.1); // 10% error allowed

    // Create LOD model - generate 3 levels
    let lod_model = lod::create_lod_model(Arc::new(mesh), 3, &simplifier, &pool);

    assert_eq!(lod_model.level_count(), 3);

    // Check level 1 (LOD 0 - original)
    let l0 = &lod_model.lod_levels[0];
    assert_eq!(l0.vertex_count(), initial_verts);

    // Check level 2 (LOD 1 - simplified)
    let l1 = &lod_model.lod_levels[1];
    println!(
        "L1: {} verts, {} indices",
        l1.vertex_count(),
        l1.index_count()
    );
    assert!(l1.index_count() < initial_indices);

    // Check level 3 (LOD 2 - more simplified)
    let l2 = &lod_model.lod_levels[2];
    println!(
        "L2: {} verts, {} indices",
        l2.vertex_count(),
        l2.index_count()
    );
    assert!(l2.index_count() < l1.index_count());
    assert!(l2.index_count() >= 12); // Min expectation
}
