//! 渲染器增强模块 - Phase 2
//! 
//! 提供目录生成、图片优化、Dioxus UI 集成等增强功能

use anyhow::Result;
use pulldown_cmark::{Parser, Options, html, Event, Tag, HeadingLevel};
use serde::{Deserialize, Serialize};

/// 目录项
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TocItem {
    /// 标题文本
    pub title: String,
    /// 标题层级 (1-6)
    pub level: u8,
    /// 锚点 ID
    pub id: String,
    /// 子目录
    pub children: Vec<TocItem>,
}

/// 目录生成器
pub struct TocGenerator {
    items: Vec<TocItem>,
    current_stack: Vec<(u8, Vec<TocItem>)>,
}

impl TocGenerator {
    /// 创建目录生成器
    pub fn new() -> Self {
        Self {
            items: Vec::new(),
            current_stack: Vec::new(),
        }
    }
    
    /// 从 Markdown 生成目录
    pub fn generate(&mut self, markdown: &str) -> Vec<TocItem> {
        let mut options = Options::empty();
        options.insert(Options::ENABLE_HEADING_ATTRIBUTES);
        
        let parser = Parser::new_ext(markdown, options);
        
        for event in parser {
            match event {
                Event::Start(Tag::Heading(level, id, _)) => {
                    let level_num = match level {
                        HeadingLevel::H1 => 1,
                        HeadingLevel::H2 => 2,
                        HeadingLevel::H3 => 3,
                        HeadingLevel::H4 => 4,
                        HeadingLevel::H5 => 5,
                        HeadingLevel::H6 => 6,
                    };
                    
                    let id_str = id.unwrap_or_default().to_string();
                    self.current_stack.push((level_num, Vec::new()));
                }
                Event::End(Tag::Heading(level, _, _)) => {
                    let level_num = match level {
                        HeadingLevel::H1 => 1,
                        HeadingLevel::H2 => 2,
                        HeadingLevel::H3 => 3,
                        HeadingLevel::H4 => 4,
                        HeadingLevel::H5 => 5,
                        HeadingLevel::H6 => 6,
                    };
                    
                    if let Some((stack_level, mut children)) = self.current_stack.pop() {
                        let title = children.iter()
                            .filter_map(|item| {
                                if let TocItem { title, .. } = item {
                                    Some(title.clone())
                                } else {
                                    None
                                }
                            })
                            .collect::<Vec<_>>()
                            .join(" ");
                        
                        let item = TocItem {
                            title,
                            level: level_num,
                            id: format!("heading-{}", level_num),
                            children: Vec::new(),
                        };
                        
                        if stack_level > 1 {
                            if let Some(parent) = self.current_stack.last_mut() {
                                parent.1.push(item);
                            }
                        } else {
                            self.items.push(item);
                        }
                    }
                }
                Event::Text(text) => {
                    if let Some(last) = self.current_stack.last_mut() {
                        last.1.push(TocItem {
                            title: text.to_string(),
                            level: 0,
                            id: String::new(),
                            children: Vec::new(),
                        });
                    }
                }
                _ => {}
            }
        }
        
        std::mem::take(&mut self.items)
    }
    
    /// 生成 HTML 目录
    pub fn to_html(&self, items: &[TocItem]) -> String {
        let mut html = String::new();
        html.push_str("<nav class=\"toc\">\n<h2>目录</h2>\n<ul>\n");
        
        for item in items {
            self.render_toc_item(&mut html, item, 0);
        }
        
        html.push_str("</ul>\n</nav>");
        html
    }
    
    fn render_toc_item(&self, html: &mut String, item: &TocItem, indent: usize) {
        let indent_str = "  ".repeat(indent);
        html.push_str(&format!(
            "{}<li><a href=\"#{}\">{}</a></li>\n",
            indent_str,
            item.id,
            item.title
        ));
        
        for child in &item.children {
            self.render_toc_item(html, child, indent + 1);
        }
    }
}

impl Default for TocGenerator {
    fn default() -> Self {
        Self::new()
    }
}

/// 图片配置
#[derive(Debug, Clone)]
pub struct ImageConfig {
    /// 最大宽度
    pub max_width: u16,
    /// 是否懒加载
    pub lazy_load: bool,
    /// 是否显示标题
    pub show_caption: bool,
    /// 图片根路径
    pub base_path: String,
}

impl Default for ImageConfig {
    fn default() -> Self {
        Self {
            max_width: 1200,
            lazy_load: true,
            show_caption: true,
            base_path: String::new(),
        }
    }
}

/// 图片处理器
pub struct ImageProcessor {
    config: ImageConfig,
}

impl ImageProcessor {
    /// 创建图片处理器
    pub fn new(config: ImageConfig) -> Self {
        Self { config }
    }
    
    /// 处理 Markdown 中的图片
    pub fn process_markdown(&self, markdown: &str) -> String {
        // 简单实现：替换图片语法，添加懒加载和尺寸限制
        let processed = markdown.replace(
            "![",
            &format!("![:{}px](", self.config.max_width)
        );
        
        processed
    }
    
    /// 生成图片 HTML
    pub fn image_to_html(&self, alt: &str, url: &str, title: Option<&str>) -> String {
        let loading = if self.config.lazy_load { "lazy" } else { "eager" };
        
        let caption = if self.config.show_caption && !alt.is_empty() {
            format!("<figcaption>{}</figcaption>", alt)
        } else {
            String::new()
        };
        
        format!(
            r#"<figure class="image">
  <img src="{}" alt="{}" loading="{}" style="max-width: {}px;">
  {}
</figure>"#,
            url,
            alt,
            loading,
            self.config.max_width,
            caption
        )
    }
}

/// Dioxus 组件属性
#[derive(Debug, Clone)]
pub struct ViewerProps {
    /// 内容
    pub content: String,
    /// 是否显示目录
    pub show_toc: bool,
    /// 主题名称
    pub theme: String,
    /// 字体大小
    pub font_size: u16,
}

impl Default for ViewerProps {
    fn default() -> Self {
        Self {
            content: String::new(),
            show_toc: true,
            theme: "dark".to_string(),
            font_size: 14,
        }
    }
}

/// 渲染增强器
pub struct EnhancedRenderer {
    toc_generator: TocGenerator,
    image_processor: ImageProcessor,
}

impl EnhancedRenderer {
    /// 创建增强渲染器
    pub fn new() -> Self {
        Self {
            toc_generator: TocGenerator::new(),
            image_processor: ImageProcessor::new(ImageConfig::default()),
        }
    }
    
    /// 渲染带目录的 Markdown
    pub fn render_markdown_with_toc(&mut self, markdown: &str) -> Result<(String, String)> {
        // 生成目录
        let toc = self.toc_generator.generate(markdown);
        let toc_html = self.toc_generator.to_html(&toc);
        
        // 处理图片
        let processed_md = self.image_processor.process_markdown(markdown);
        
        // 渲染 Markdown
        let mut options = Options::empty();
        options.insert(Options::ENABLE_STRIKETHROUGH);
        options.insert(Options::ENABLE_TABLES);
        options.insert(Options::ENABLE_TASKLISTS);
        options.insert(Options::ENABLE_HEADING_ATTRIBUTES);
        
        let parser = Parser::new_ext(&processed_md, options);
        let mut html_output = String::new();
        html::push_html(&mut html_output, parser);
        
        Ok((toc_html, html_output))
    }
    
    /// 获取纯目录结构
    pub fn get_toc(&mut self, markdown: &str) -> Vec<TocItem> {
        self.toc_generator.generate(markdown)
    }
}

impl Default for EnhancedRenderer {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_toc_generation() {
        let mut generator = TocGenerator::new();
        let markdown = r#"
# 第一章
## 1.1 节
## 1.2 节
# 第二章
## 2.1 节
"#;
        
        let toc = generator.generate(markdown);
        assert!(!toc.is_empty());
    }
    
    #[test]
    fn test_enhanced_renderer() {
        let mut renderer = EnhancedRenderer::new();
        let markdown = r#"
# 标题

这是一段文本。

## 子标题

更多内容。
"#;
        
        let result = renderer.render_markdown_with_toc(markdown);
        assert!(result.is_ok());
        
        let (toc_html, content_html) = result.unwrap();
        assert!(toc_html.contains("<nav class=\"toc\">"));
        assert!(content_html.contains("<h1>"));
    }
    
    #[test]
    fn test_image_processor() {
        let processor = ImageProcessor::new(ImageConfig::default());
        let html = processor.image_to_html("测试图片", "test.png", Some("标题"));
        
        assert!(html.contains("<img"));
        assert!(html.contains("loading=\"lazy\""));
        assert!(html.contains("max-width: 1200px"));
    }
}
