use crate::events::{Consumer, Emitter, Event};
use crate::parsers::selectors::StackFrameCollector;
use crate::transformers::Transformer;
use std::collections::VecDeque;
use std::sync::{Arc, Mutex};

/// A transformer that filters events based on CSS-like selectors.
/// It maintains a stack representation of the document structure and
/// only re-emits events when the current context matches one of the selectors.
pub struct SelectorTransformer {
    /// Stack frame collector for selector matching
    collector: StackFrameCollector,
    /// Storage for events that match selectors
    matching_events: Arc<Mutex<VecDeque<Event>>>,
}

impl SelectorTransformer {
    /// Create a new SelectorTransformer with the given selector strings
    pub fn new(selector_strings: Vec<String>) -> Self {
        let collector = StackFrameCollector::new(selector_strings);

        Self {
            collector,
            matching_events: Arc::new(Mutex::new(VecDeque::new())),
        }
    }

    /// Check if any of our selectors match the current stack
    fn matches_any_selector(&self) -> bool {
        self.collector.matches_any_selector()
    }

    /// Clear all stored events
    pub fn clear(&mut self) {
        if let Ok(mut events) = self.matching_events.lock() {
            events.clear();
        }
    }
}

impl Consumer for SelectorTransformer {
    fn handle(&mut self, event: Event) {
        match &event {
            Event::BlockStarted { .. } => {
                // Update the collector
                self.collector.handle_event(&event);

                if self.matches_any_selector() {
                    if let Ok(mut events) = self.matching_events.lock() {
                        events.push_back(event.clone());
                    }
                }
            }
            Event::BlockFinished => {
                if self.matches_any_selector() {
                    if let Ok(mut events) = self.matching_events.lock() {
                        events.push_back(event.clone());
                    }
                }

                // Update the collector
                self.collector.handle_event(&event);
            }
            Event::TextFinished { .. } => {
                // If we're emitting, pass through text events
                if self.matches_any_selector() {
                    if let Ok(mut events) = self.matching_events.lock() {
                        events.push_back(event.clone());
                    }
                }
            }
            Event::ContextLine { .. } => {
                // If we're emitting, pass through context line events
                if self.matches_any_selector() {
                    if let Ok(mut events) = self.matching_events.lock() {
                        events.push_back(event.clone());
                    }
                }
            }
            Event::VoidElement { .. } => {
                // Void elements are self-closing (no stack changes)
                // If we're emitting, pass through void element events
                if self.matches_any_selector() {
                    if let Ok(mut events) = self.matching_events.lock() {
                        events.push_back(event.clone());
                    }
                }
            }
        }
    }

    fn on_start(&mut self) {}

    fn on_finish(&mut self) {
        // Nothing special to do on finish
    }
}

/// Iterator for reading filtered events from the SelectorTransformer
pub struct SelectorTransformerIterator {
    events: Arc<Mutex<VecDeque<Event>>>,
}

impl Iterator for SelectorTransformerIterator {
    type Item = Event;

    fn next(&mut self) -> Option<Self::Item> {
        if let Ok(mut events) = self.events.lock() {
            events.pop_front()
        } else {
            None
        }
    }
}

impl Emitter for SelectorTransformer {
    type Reader = SelectorTransformerIterator;

    fn subscribe(&self) -> Self::Reader {
        SelectorTransformerIterator {
            events: Arc::clone(&self.matching_events),
        }
    }

    fn run(self) {
        // For a transformer, run doesn't need to do anything special
        // The events are emitted as they are consumed
    }
}

impl Transformer for SelectorTransformer {}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::parsers::wasot::{Id, MetaLine, ParsedArguments, QuotedString};

    #[test]
    fn test_selector_parsing() {
        let transformer = SelectorTransformer::new(vec![
            "paragraph".to_string(),
            "section > paragraph".to_string(),
            "document paragraph".to_string(),
        ]);

        // Should have successfully parsed all 3 selectors
        assert_eq!(transformer.collector.selector_count(), 3);
    }

    #[test]
    fn test_selector_matching_and_emitting() {
        let mut transformer = SelectorTransformer::new(vec!["section paragraph".to_string()]);

        // Create a section block start event
        let section_event = Event::BlockStarted {
            meta_line: MetaLine {
                level: 1,
                type_name: "section".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(0),
                is_void: false,
            },
        };

        // Process section start - shouldn't emit yet
        transformer.handle(section_event);
        let mut reader = transformer.subscribe();
        assert!(
            reader.next().is_none(),
            "Section alone shouldn't match 'section paragraph'"
        );

        // Create a paragraph block start event
        let paragraph_event = Event::BlockStarted {
            meta_line: MetaLine {
                level: 2,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(1),
                is_void: false,
            },
        };

        // Process paragraph start - should emit now
        transformer.handle(paragraph_event);
        let mut reader = transformer.subscribe();
        let emitted = reader.next();
        assert!(
            emitted.is_some(),
            "Should emit paragraph when selector matches"
        );
        if let Some(Event::BlockStarted { meta_line }) = emitted {
            assert_eq!(meta_line.type_name, "paragraph");
        } else {
            panic!("Expected BlockStarted event");
        }

        // Text in the paragraph should also be emitted
        let text_event = Event::TextFinished {
            lines: vec!["Test content".to_string()],
            links: vec![vec![]],
            footnotes: vec![],
        };
        transformer.handle(text_event);
        let mut reader = transformer.subscribe();
        assert!(
            reader.next().is_some(),
            "Text should be emitted when inside matching block"
        );

        // BlockFinished for paragraph
        transformer.handle(Event::BlockFinished);
        let mut reader = transformer.subscribe();
        assert!(reader.next().is_some(), "BlockFinished should be emitted");

        // BlockFinished for section
        transformer.handle(Event::BlockFinished);
        let mut reader = transformer.subscribe();
        assert!(
            reader.next().is_none(),
            "Section BlockFinished shouldn't be emitted"
        );
    }

    #[test]
    fn test_invalid_selector_handling() {
        let transformer = SelectorTransformer::new(vec![
            ">".to_string(), // Invalid selector
            "valid".to_string(),
            "div > > p".to_string(), // Another invalid
        ]);

        // Should still work with valid selectors
        assert_eq!(transformer.collector.selector_count(), 1);
        assert_eq!(transformer.collector.selector_string(0), Some("valid"));
    }

    #[test]
    fn test_empty_selector_list() {
        let transformer = SelectorTransformer::new(vec![]);
        assert_eq!(transformer.collector.selector_count(), 0);
        assert!(!transformer.matches_any_selector());
    }

    #[test]
    fn test_multiple_selector_matching() {
        let mut transformer = SelectorTransformer::new(vec![
            "paragraph".to_string(),
            "section > paragraph".to_string(),
            "document paragraph".to_string(),
        ]);

        // Single paragraph should match first selector
        let para_event = Event::BlockStarted {
            meta_line: MetaLine {
                level: 1,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(0),
                is_void: false,
            },
        };

        transformer.handle(para_event);
        let mut reader = transformer.subscribe();
        assert!(reader.next().is_some());
    }

    #[test]
    fn test_child_index_reset_on_level_change() {
        let mut transformer = SelectorTransformer::new(vec!["paragraph:nth-child(2)".to_string()]);

        // Create section with two paragraphs
        transformer.handle(Event::BlockStarted {
            meta_line: MetaLine {
                level: 1,
                type_name: "section".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(0),
                is_void: false,
            },
        });

        // First paragraph (child index 0)
        transformer.handle(Event::BlockStarted {
            meta_line: MetaLine {
                level: 2,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(1),
                is_void: false,
            },
        });
        let mut reader = transformer.subscribe();
        assert!(reader.next().is_none()); // Not second child

        transformer.handle(Event::BlockFinished);

        // Second paragraph (child index 1)
        transformer.handle(Event::BlockStarted {
            meta_line: MetaLine {
                level: 2,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(2),
                is_void: false,
            },
        });
        let mut reader = transformer.subscribe();
        assert!(reader.next().is_some()); // Should match nth-child(2)
    }

    #[test]
    fn test_deeply_nested_structure() {
        let mut transformer =
            SelectorTransformer::new(vec!["document section article paragraph".to_string()]);

        // Build deep structure
        let types = ["document", "section", "article", "paragraph"];
        for (i, type_name) in types.iter().enumerate() {
            transformer.handle(Event::BlockStarted {
                meta_line: MetaLine {
                    level: i + 1,
                    type_name: type_name.to_string(),
                    id: Id::new("".to_string()),
                    arguments: ParsedArguments {
                        args: vec![],
                        kwargs: vec![],
                    },
                    inline_text: QuotedString::new("".to_string(), false),
                    line_index: Some(i),
                    is_void: false,
                },
            });
        }

        // Only the paragraph should be emitted
        let mut reader = transformer.subscribe();
        let mut emitted_count = 0;
        while reader.next().is_some() {
            emitted_count += 1;
        }
        assert_eq!(emitted_count, 1);

        // Unwind and verify cleanup
        for _ in 0..4 {
            transformer.handle(Event::BlockFinished);
        }
        assert_eq!(transformer.collector.depth(), 0);
    }

    #[test]
    fn test_text_event_without_matching() {
        let mut transformer = SelectorTransformer::new(vec!["paragraph".to_string()]);

        // Send text event without any matching block
        transformer.handle(Event::TextFinished {
            lines: vec!["Test".to_string()],
            links: vec![vec![]],
            footnotes: vec![],
        });

        // Should not emit anything
        let mut reader = transformer.subscribe();
        assert!(reader.next().is_none());
    }

    #[test]
    fn test_transition_from_matching_to_non_matching() {
        let mut transformer = SelectorTransformer::new(vec!["section paragraph".to_string()]);

        // Section
        transformer.handle(Event::BlockStarted {
            meta_line: MetaLine {
                level: 1,
                type_name: "section".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(0),
                is_void: false,
            },
        });

        // Paragraph (matches)
        transformer.handle(Event::BlockStarted {
            meta_line: MetaLine {
                level: 2,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(1),
                is_void: false,
            },
        });
        let mut reader = transformer.subscribe();
        assert!(reader.next().is_some());

        // Div inside paragraph - with matches_prefix, the selector still matches the prefix
        // but we're checking if we emit the div BlockStarted after clearing previous events
        transformer.handle(Event::BlockStarted {
            meta_line: MetaLine {
                level: 3,
                type_name: "div".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(2),
                is_void: false,
            },
        });
        // At this point, the stack is [section, paragraph, div]
        // The selector "section paragraph" matches the prefix [section, paragraph]
        // So emitting should be true and the div's BlockStarted should have been emitted
        let mut reader = transformer.subscribe();
        assert!(reader.next().is_some()); // Should emit div's BlockStarted since we're in emitting state

        // Finish div - we're still in emitting state
        transformer.handle(Event::BlockFinished);
        let mut reader = transformer.subscribe();
        assert!(reader.next().is_some()); // Should emit BlockFinished for div since we're emitting

        // Finish paragraph
        transformer.handle(Event::BlockFinished);
        let mut reader = transformer.subscribe();
        assert!(reader.next().is_some());

        // Now in section only - should not emit
        transformer.handle(Event::TextFinished {
            lines: vec!["Text in section".to_string()],
            links: vec![vec![]],
            footnotes: vec![],
        });
        transformer.clear(); // Clear previous events
        let mut reader = transformer.subscribe();
        assert!(reader.next().is_none());
    }

    #[test]
    fn test_transformer_as_pipeline() {
        let mut transformer = SelectorTransformer::new(vec!["paragraph".to_string()]);

        // Process multiple events
        let events = vec![
            Event::BlockStarted {
                meta_line: MetaLine {
                    level: 1,
                    type_name: "document".to_string(),
                    id: Id::new("".to_string()),
                    arguments: ParsedArguments {
                        args: vec![],
                        kwargs: vec![],
                    },
                    inline_text: QuotedString::new("".to_string(), false),
                    line_index: Some(0),
                    is_void: false,
                },
            },
            Event::BlockStarted {
                meta_line: MetaLine {
                    level: 2,
                    type_name: "paragraph".to_string(),
                    id: Id::new("".to_string()),
                    arguments: ParsedArguments {
                        args: vec![],
                        kwargs: vec![],
                    },
                    inline_text: QuotedString::new("".to_string(), false),
                    line_index: Some(1),
                    is_void: false,
                },
            },
            Event::TextFinished {
                lines: vec!["Matching text".to_string()],
                links: vec![vec![]],
                footnotes: vec![],
            },
            Event::BlockFinished,
            Event::BlockFinished,
        ];

        // Process all events
        for event in events {
            transformer.handle(event);
        }

        // Should have emitted: paragraph start, text, paragraph end
        let reader = transformer.subscribe();
        let collected: Vec<Event> = reader.collect();
        assert_eq!(collected.len(), 3);

        // Verify the types of emitted events
        assert!(matches!(collected[0], Event::BlockStarted { .. }));
        assert!(matches!(collected[1], Event::TextFinished { .. }));
        assert!(matches!(collected[2], Event::BlockFinished));
    }

    #[test]
    fn test_section_selector_includes_children() {
        let mut transformer = SelectorTransformer::new(vec!["section".to_string()]);
        let reader = transformer.subscribe();

        // This should not be caputes
        transformer.handle(Event::BlockStarted {
            meta_line: MetaLine::parse(".outer", 0).expect("should parse"),
        });

        // Process a section with children
        transformer.handle(Event::BlockStarted {
            meta_line: MetaLine::parse("..section", 0).expect("should parse"),
        });

        // Add a child paragraph
        transformer.handle(Event::BlockStarted {
            meta_line: MetaLine::parse("...paragraph", 0).expect("should parse"),
        });

        // Add text in paragraph
        transformer.handle(Event::TextFinished {
            lines: vec!["Child text".to_string()],
            links: vec![vec![]],
            footnotes: vec![],
        });

        // Close paragraph
        transformer.handle(Event::BlockFinished);

        // Close section
        transformer.handle(Event::BlockFinished);

        // Close outer
        transformer.handle(Event::BlockFinished);

        // Collect emitted events
        let collected: Vec<Event> = reader.collect();

        // Should emit all 5 events: section start, para start, text, para end, section end
        assert_eq!(
            collected.len(),
            5,
            "Should emit all events within matching section"
        );

        // Verify event types -> nested included, outside not!
        assert!(
            matches!(collected[0], Event::BlockStarted { ref meta_line } if meta_line.type_name == "section")
        );
        assert!(
            matches!(collected[1], Event::BlockStarted { ref meta_line } if meta_line.type_name == "paragraph")
        );
        assert!(matches!(collected[2], Event::TextFinished { .. }));
        assert!(matches!(collected[3], Event::BlockFinished));
        assert!(matches!(collected[4], Event::BlockFinished));
    }

    #[test]
    fn test_new_constructor_specific_lines() {
        // Test lines 19-20 in function `new` - creating StackFrameCollector
        let selectors = vec!["paragraph".to_string(), "section".to_string()];
        let transformer = SelectorTransformer::new(selectors.clone());

        // Verify that StackFrameCollector was created with the selectors
        assert_eq!(transformer.collector.selector_count(), 2);

        // Test line 24 in function `new` - creating Arc<Mutex<VecDeque>>
        // Verify we can lock and use the matching_events queue
        let events_guard = transformer.matching_events.lock();
        assert!(events_guard.is_ok());
        assert_eq!(events_guard.unwrap().len(), 0);
    }

    #[test]
    fn test_matches_any_selector_specific_lines() {
        let mut transformer = SelectorTransformer::new(vec!["paragraph".to_string()]);

        // Initially should not match anything
        // Test lines 29-30 in function `matches_any_selector`
        assert!(!transformer.matches_any_selector());

        // Add a matching block
        transformer.handle(Event::BlockStarted {
            meta_line: MetaLine {
                level: 1,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(0),
                is_void: false,
            },
        });

        // Now should match
        assert!(transformer.matches_any_selector());
    }

    #[test]
    fn test_clear_specific_lines() {
        let mut transformer = SelectorTransformer::new(vec!["paragraph".to_string()]);

        // Add some events to queue
        transformer.handle(Event::BlockStarted {
            meta_line: MetaLine {
                level: 1,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(0),
                is_void: false,
            },
        });

        // Verify events were added
        let reader = transformer.subscribe();
        let initial_count = reader.count();
        assert!(initial_count > 0);

        // Test lines 34-36 in function `clear`
        transformer.clear();

        // Verify events were cleared
        let reader = transformer.subscribe();
        let after_clear_count = reader.count();
        assert_eq!(after_clear_count, 0);
    }

    #[test]
    fn test_handle_event_match_specific_lines() {
        let mut transformer = SelectorTransformer::new(vec!["paragraph".to_string()]);

        // Create a matching event
        let event = Event::BlockStarted {
            meta_line: MetaLine {
                level: 1,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(0),
                is_void: false,
            },
        };

        // Test lines 42-43 in function `handle` - match arm and collector update
        transformer.handle(event.clone());

        // Verify the event was processed and emitted
        let reader = transformer.subscribe();
        let emitted_events: Vec<Event> = reader.collect();
        assert_eq!(emitted_events.len(), 1);
        assert!(matches!(emitted_events[0], Event::BlockStarted { .. }));
    }

    #[test]
    fn test_block_started_collector_update_line_46() {
        let mut transformer = SelectorTransformer::new(vec!["section".to_string()]);

        // Create a non-matching event first to test collector update
        let event = Event::BlockStarted {
            meta_line: MetaLine {
                level: 1,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(0),
                is_void: false,
            },
        };

        let initial_depth = transformer.collector.depth();

        // Test line 46: self.collector.handle_event(&event); for BlockStarted
        transformer.handle(event);

        // Verify collector was updated (depth increased)
        assert_eq!(transformer.collector.depth(), initial_depth + 1);

        // Should not have emitted anything since it doesn't match
        let reader = transformer.subscribe();
        assert_eq!(reader.count(), 0);
    }

    #[test]
    fn test_block_started_matching_emission_lines_48_50() {
        let mut transformer = SelectorTransformer::new(vec!["paragraph".to_string()]);

        // Create a matching event
        let event = Event::BlockStarted {
            meta_line: MetaLine {
                level: 1,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(0),
                is_void: false,
            },
        };

        // Test lines 48-50: if self.matches_any_selector() { ... events.push_back(event.clone()); }
        transformer.handle(event.clone());

        // Verify event was emitted due to matching
        let reader = transformer.subscribe();
        let events: Vec<Event> = reader.collect();
        assert_eq!(events.len(), 1);
        assert!(matches!(events[0], Event::BlockStarted { .. }));
    }

    #[test]
    fn test_block_finished_matching_emission_lines_55_57() {
        let mut transformer = SelectorTransformer::new(vec!["paragraph".to_string()]);

        // Set up a matching context first
        let start_event = Event::BlockStarted {
            meta_line: MetaLine {
                level: 1,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(0),
                is_void: false,
            },
        };
        transformer.handle(start_event);

        // Clear previous events to test only BlockFinished
        transformer.clear();

        // Test lines 55-57: if self.matches_any_selector() { ... events.push_back(event.clone()); }
        transformer.handle(Event::BlockFinished);

        // Verify BlockFinished was emitted due to matching context
        let reader = transformer.subscribe();
        let events: Vec<Event> = reader.collect();
        assert_eq!(events.len(), 1);
        assert!(matches!(events[0], Event::BlockFinished));
    }

    #[test]
    fn test_block_finished_collector_update_line_62() {
        let mut transformer = SelectorTransformer::new(vec!["section".to_string()]);

        // Set up a block context first
        let start_event = Event::BlockStarted {
            meta_line: MetaLine {
                level: 1,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(0),
                is_void: false,
            },
        };
        transformer.handle(start_event);

        let initial_depth = transformer.collector.depth();

        // Test line 62: self.collector.handle_event(&event); for BlockFinished
        transformer.handle(Event::BlockFinished);

        // Verify collector was updated (depth decreased)
        assert_eq!(transformer.collector.depth(), initial_depth - 1);
    }

    #[test]
    fn test_text_finished_matching_emission_lines_66_68() {
        let mut transformer = SelectorTransformer::new(vec!["paragraph".to_string()]);

        // Set up a matching context first
        let start_event = Event::BlockStarted {
            meta_line: MetaLine {
                level: 1,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(0),
                is_void: false,
            },
        };
        transformer.handle(start_event);
        transformer.clear(); // Clear to test only TextFinished

        let text_event = Event::TextFinished {
            lines: vec!["Test text".to_string()],
            links: vec![vec![]],
            footnotes: vec![],
        };

        // Test lines 66-68: if self.matches_any_selector() { ... events.push_back(event.clone()); }
        transformer.handle(text_event.clone());

        // Verify text event was emitted due to matching context
        let reader = transformer.subscribe();
        let events: Vec<Event> = reader.collect();
        assert_eq!(events.len(), 1);
        assert!(matches!(events[0], Event::TextFinished { .. }));
    }

    #[test]
    fn test_on_start_line_75() {
        let mut transformer = SelectorTransformer::new(vec!["paragraph".to_string()]);

        // Test line 75: fn on_start(&mut self) {} - empty implementation
        transformer.on_start(); // Should not panic or do anything

        // Verify state is unchanged
        assert!(!transformer.matches_any_selector());
        assert_eq!(transformer.collector.depth(), 0);
    }

    #[test]
    fn test_on_finish_line_77() {
        let mut transformer = SelectorTransformer::new(vec!["paragraph".to_string()]);

        // Set up some state
        let start_event = Event::BlockStarted {
            meta_line: MetaLine {
                level: 1,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(0),
                is_void: false,
            },
        };
        transformer.handle(start_event);

        // Test line 77: fn on_finish(&mut self) { // Nothing special to do on finish }
        transformer.on_finish(); // Should not panic or change state

        // Verify state is preserved
        assert!(transformer.matches_any_selector());
        assert_eq!(transformer.collector.depth(), 1);
    }

    #[test]
    fn test_iterator_next_success_lines_90_92() {
        let mut transformer = SelectorTransformer::new(vec!["paragraph".to_string()]);

        // Add an event to the queue
        transformer.handle(Event::BlockStarted {
            meta_line: MetaLine {
                level: 1,
                type_name: "paragraph".to_string(),
                id: Id::new("".to_string()),
                arguments: ParsedArguments {
                    args: vec![],
                    kwargs: vec![],
                },
                inline_text: QuotedString::new("".to_string(), false),
                line_index: Some(0),
                is_void: false,
            },
        });

        let mut reader = transformer.subscribe();

        // Test lines 90-92: if let Ok(mut events) = self.events.lock() { events.pop_front() }
        let event = reader.next();
        assert!(event.is_some());
        assert!(matches!(event.unwrap(), Event::BlockStarted { .. }));

        // Second call should return None (empty queue)
        let event2 = reader.next();
        assert!(event2.is_none());
    }

    #[test]
    fn test_subscribe_lines_102_104() {
        let transformer = SelectorTransformer::new(vec!["paragraph".to_string()]);

        // Test line 102: fn subscribe(&self) -> Self::Reader
        // Test line 104: events: Arc::clone(&self.matching_events)
        let reader = transformer.subscribe();

        // Verify reader was created successfully and can be used
        let count = reader.count();
        assert_eq!(count, 0); // No events initially
    }

    #[test]
    fn test_run_line_108() {
        let transformer = SelectorTransformer::new(vec!["paragraph".to_string()]);

        // Test line 108: fn run(self) { // For a transformer, run doesn't need to do anything special }
        // This should not panic and should complete normally
        transformer.run();

        // If we reach here, the run method completed successfully
    }

    #[test]
    fn test_iterator_next_lock_failure_line_94() {
        use std::collections::VecDeque;
        use std::sync::{Arc, Mutex};

        // Create iterator with events Arc directly to simulate potential lock failure
        let events = Arc::new(Mutex::new(VecDeque::<Event>::new()));
        let mut iterator = SelectorTransformerIterator {
            events: Arc::clone(&events),
        };

        // In normal circumstances, lock shouldn't fail, but we can test the code path
        // by checking what happens when we call next() on an empty queue
        let result = iterator.next();

        // Test line 94: None (when lock succeeds but queue is empty)
        // Since we can't easily trigger a lock failure in tests without complex setup,
        // we test the successful lock path with empty queue which returns None
        assert!(result.is_none());
    }

    #[test]
    fn test_selector_transformer_with_whitespace_selectors() {
        // Test edge case with selectors containing extra whitespace
        let transformer =
            SelectorTransformer::new(vec!["  paragraph  ".to_string(), "\tsection\t".to_string()]);

        // Should still parse selectors correctly despite whitespace
        assert_eq!(transformer.collector.selector_count(), 2);
    }
}
