use super::*;

/// Applies one interactive Material edit to both the authored document and the renderer overlay.
/// No filesystem, watcher, Git, thumbnail, or derived-processing work is performed here.
pub fn update_material_document(
    world: &mut World,
    key: &AuthoredAssetDocumentKey,
    asset: MaterialAsset,
) {
    let revision = {
        let mut store = world.resource_mut::<AuthoredAssetDocumentStore>();
        store.update_material(key, asset.clone());
        store
            .documents
            .get(key)
            .map(|document| document.revision)
            .unwrap_or_default()
    };
    if let Some(mut overlay) =
        world.get_resource_mut::<blacksite_surface::LiveMaterialDocumentOverlay>()
    {
        overlay.update_material(key.asset_id.clone(), revision, asset);
    }
}

/// Applies one interactive Material Instance edit to the same live authority as Materials.
pub fn update_material_instance_document(
    world: &mut World,
    key: &AuthoredAssetDocumentKey,
    instance: MaterialInstanceAsset,
) {
    let revision = {
        let mut store = world.resource_mut::<AuthoredAssetDocumentStore>();
        store.update_material_instance(key, instance.clone());
        store
            .documents
            .get(key)
            .map(|document| document.revision)
            .unwrap_or_default()
    };
    if let Some(mut overlay) =
        world.get_resource_mut::<blacksite_surface::LiveMaterialDocumentOverlay>()
    {
        overlay.update_instance(key.asset_id.clone(), revision, instance);
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    fn material(label: &str) -> MaterialAsset {
        MaterialAsset {
            schema_version: shared::MATERIAL_ASSET_SCHEMA_VERSION,
            label: label.into(),
            shader: Default::default(),
            shader_ref: None,
            render_state: Default::default(),
            provenance: None,
            inputs: Default::default(),
        }
    }

    #[test]
    fn live_edit_marks_one_document_dirty_without_writing_or_queueing_processing() {
        let path = std::env::temp_dir().join(format!(
            "blacksite-live-edit-no-publish-{}.material.ron",
            uuid::Uuid::new_v4()
        ));
        std::fs::write(&path, b"disk baseline").unwrap();
        let key = AuthoredAssetDocumentKey::new(
            "live-edit-material",
            AuthoredAssetDocumentKind::Material,
        );
        let mut store = AuthoredAssetDocumentStore::default();
        store.documents.insert(
            key.clone(),
            AuthoredAssetDocument::new(
                key.clone(),
                path.to_string_lossy().into_owned(),
                AuthoredAssetValue::Material(material("Clean")),
                FileSnapshot::capture(&path).unwrap(),
            ),
        );
        let mut world = World::new();
        world.insert_resource(store);
        world.init_resource::<ContentProcessingQueue>();
        world.init_resource::<blacksite_surface::LiveMaterialDocumentOverlay>();

        update_material_document(&mut world, &key, material("Live edit"));

        assert_eq!(std::fs::read(&path).unwrap(), b"disk baseline");
        let snapshot = world
            .resource::<AuthoredAssetDocumentStore>()
            .snapshot(&key)
            .unwrap();
        assert!(snapshot.dirty);
        assert_eq!(snapshot.state, AuthoredDocumentState::Dirty);
        let queue = world.resource::<ContentProcessingQueue>();
        assert!(queue.pending.is_empty());
        assert!(queue.active.is_none());
        assert_eq!(
            world
                .resource::<blacksite_surface::LiveMaterialDocumentOverlay>()
                .revision_for_asset(&key.asset_id),
            Some(1)
        );

        std::fs::remove_file(path).unwrap();
    }
}
