use serde::{Deserialize, Serialize};
use uuid::Uuid;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RichTextBlock {
    pub block_type: BlockType,
    pub content: String,
    pub attributes: Option<serde_json::Value>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum BlockType {
    Text,
    Code,
    Quote,
    Link,
    Mention,
    Emoji,
    Image,
}

pub struct RichTextRenderer;

impl RichTextRenderer {
    pub fn new() -> Self {
        Self {}
    }

    pub fn parse_markdown(&self, content: &str) -> Vec<RichTextBlock> {
        vec![RichTextBlock {
            block_type: BlockType::Text,
            content: content.to_string(),
            attributes: None,
        }]
    }

    pub fn parse_mentions(&self, content: &str) -> Vec<Uuid> {
        content
            .split_whitespace()
            .filter(|w| w.starts_with('@'))
            .filter_map(|w| Uuid::parse_str(&w[1..]).ok())
            .collect()
    }

    pub fn highlight_code(&self, code: &str, language: &str) -> String {
        format!("```{}\n{}\n```", language, code)
    }

    pub fn render_to_html(&self, blocks: &[RichTextBlock]) -> String {
        blocks
            .iter()
            .map(|block| match block.block_type {
                BlockType::Text => {
                    format!("<p>{}</p>", html_escape(&block.content))
                }
                BlockType::Code => format!(
                    "<pre><code>{}</code></pre>",
                    html_escape(&block.content)
                ),
                BlockType::Quote => format!(
                    "<blockquote>{}</blockquote>",
                    html_escape(&block.content)
                ),
                BlockType::Link => {
                    let safe_href = sanitize_uri(&block.content);
                    format!(
                        "<a href=\"{}\">{}</a>",
                        html_escape(&safe_href),
                        html_escape(&block.content)
                    )
                }
                BlockType::Mention => format!(
                    "<span class=\"mention\">@{}</span>",
                    html_escape(&block.content)
                ),
                BlockType::Emoji => format!(
                    "<span class=\"emoji\">{}</span>",
                    html_escape(&block.content)
                ),
                BlockType::Image => {
                    let safe_src = sanitize_uri(&block.content);
                    if safe_src.is_empty() {
                        String::new()
                    } else {
                        format!("<img src=\"{}\" />", html_escape(&safe_src))
                    }
                }
            })
            .collect::<Vec<_>>()
            .join("\n")
    }
}
fn sanitize_uri(uri: &str) -> String {
    let lower = uri.to_lowercase();
    if lower.starts_with("http://")
        || lower.starts_with("https://")
        || lower.starts_with("mailto:")
    {
        uri.to_string()
    } else {
        String::new()
    }
}

fn html_escape(s: &str) -> String {
    s.replace('&', "&amp;")
        .replace('<', "&lt;")
        .replace('>', "&gt;")
        .replace('"', "&quot;")
        .replace('\'', "&#x27;")
}
