use markdown_it::parser::block::{BlockRule, BlockState};
use markdown_it::parser::core::Root;
use markdown_it::{Node, NodeValue, Renderer};

//
// MARK: yaml
//

#[derive(Debug)]
pub struct YamlFrontMatter {
	#[expect(dead_code)]
	pub content: String,
}

impl NodeValue for YamlFrontMatter {
	fn render(&self, _node: &Node, _fmt: &mut dyn Renderer) {}
}

impl BlockRule for YamlFrontMatter {
	fn run(state: &mut BlockState<'_, '_>) -> Option<(Node, usize)> {
		// check the parent is the document Root
		if !state.node.is::<Root>() {
			return None;
		}

		// check we are on the first line of the document
		if state.line != 0 {
			return None;
		}

		// check line starts with opening dashes
		let opening = state
			.get_line(state.line)
			.chars()
			.take_while(|c| *c == '-')
			.collect::<String>();
		if !opening.starts_with("---") {
			return None;
		}

		// Search for the end of the block
		let mut next_line = state.line;
		loop {
			next_line += 1;
			if next_line >= state.line_max {
				return None;
			}

			let line = state.get_line(next_line);
			if line.starts_with(&opening) {
				break;
			}
		}

		let (content, _) = state.get_lines(state.line + 1, next_line, 0, true);
		Some((Node::new(YamlFrontMatter { content }), next_line + 1))
	}
}

//
// MARK: toml
//

#[derive(Debug)]
pub struct TomlFrontMatter {
	pub content: String,
}

impl NodeValue for TomlFrontMatter {
	fn render(&self, _node: &Node, _fmt: &mut dyn Renderer) {}
}

impl BlockRule for TomlFrontMatter {
	fn run(state: &mut BlockState<'_, '_>) -> Option<(Node, usize)> {
		if !state.node.is::<Root>() {
			return None;
		}

		if state.line != 0 {
			return None;
		}

		let opening = state
			.get_line(state.line)
			.chars()
			.take_while(|c| *c == '+')
			.collect::<String>();
		if !opening.starts_with("+++") {
			return None;
		}

		let mut next_line = state.line;
		loop {
			next_line += 1;
			if next_line >= state.line_max {
				return None;
			}

			let line = state.get_line(next_line);
			if line.starts_with(&opening) {
				break;
			}
		}

		let (content, _) = state.get_lines(state.line + 1, next_line, 0, true);
		Some((Node::new(TomlFrontMatter { content }), next_line + 1))
	}
}
