// SPDX-FileCopyrightText: 2026 The Frogue contributors
// SPDX-License-Identifier: AGPL-3.0-or-later

//! Integration tests for ActivityPub mentions and hashtags

#[cfg(test)]
mod tests {
    use frogue::markdown::render;
    use frogue::mentions::{MentionRequest, ResolvedMention, parse};

    #[test]
    fn test_parse_mentions_simple() {
        let text = "Hello @alice and @bob@example.com!";
        let (mentions, hashtags) = parse(text);

        assert_eq!(mentions.len(), 2);
        assert_eq!(mentions[0].username, "alice");
        assert!(mentions[0].host.is_none());

        assert_eq!(mentions[1].username, "bob");
        assert_eq!(mentions[1].host, Some("example.com".to_string()));

        assert_eq!(hashtags.len(), 0);
    }

    #[test]
    fn test_parse_hashtags_simple() {
        let text = "Check out #rust and #ActivityPub!";
        let (mentions, hashtags) = parse(text);

        assert_eq!(mentions.len(), 0);
        assert_eq!(hashtags.len(), 2);
        assert_eq!(hashtags[0], "rust");
        assert_eq!(hashtags[1], "ActivityPub");
    }

    #[test]
    fn test_parse_mixed() {
        let text = "Hello @alice! Check out #rust @bob@example.com #ActivityPub";
        let (mentions, hashtags) = parse(text);

        assert_eq!(mentions.len(), 2);
        assert_eq!(hashtags.len(), 2);
    }

    #[test]
    fn test_parse_mentions_in_code_block() {
        let text = "Don't mention @alice in this code:\n```\n@bob\n```\nand `@charlie`";
        let (mentions, _hashtags) = parse(text);

        // Only the mention outside code should be found
        assert_eq!(mentions.len(), 1);
        assert_eq!(mentions[0].username, "alice");
    }

    #[test]
    fn test_parse_hashtag_with_numbers() {
        let text = "Issue #123 and tag #rust2024";
        let (_mentions, hashtags) = parse(text);

        // #123 is a number, not a hashtag
        // #rust2024 is a valid hashtag
        assert_eq!(hashtags.len(), 1);
        assert_eq!(hashtags[0], "rust2024");
    }

    #[test]
    fn test_mention_request_handle_format() {
        let local = MentionRequest {
            username: "alice".to_string(),
            host: None,
        };
        assert_eq!(local.handle(), "@alice");

        let remote = MentionRequest {
            username: "bob".to_string(),
            host: Some("example.com".to_string()),
        };
        assert_eq!(remote.handle(), "@bob@example.com");
    }

    #[test]
    fn test_resolved_mention_properties() {
        let mention = ResolvedMention {
            handle: "@alice".to_string(),
            href: "https://example.com/users/alice".to_string(),
        };

        assert_eq!(mention.handle, "@alice");
        assert_eq!(mention.href, "https://example.com/users/alice");
    }

    #[test]
    fn test_render_hashtags_in_html() {
        let text = "Check out #rust and #ActivityPub!";
        let html = render(text);

        // Hashtags should be rendered as links
        assert!(html.contains("#rust"));
        assert!(html.contains("#ActivityPub"));
        // Should contain anchor tags
        assert!(html.contains("<a href="));
    }

    #[test]
    fn test_render_mentions_in_html() {
        let text = "Hello @alice and @bob@example.com!";
        let html = render(text);

        // Mentions should be rendered as text (actual resolution happens at AP
        // level)
        assert!(html.contains("@alice"));
        assert!(html.contains("@bob@example.com"));
    }

    #[test]
    fn test_render_mixed_mentions_and_hashtags() {
        let text = "Hello @alice! Check out #rust @bob@example.com #ActivityPub";
        let html = render(text);

        assert!(html.contains("@alice"));
        assert!(html.contains("@bob@example.com"));
        assert!(html.contains("#rust"));
        assert!(html.contains("#ActivityPub"));
    }

    #[test]
    fn test_empty_text() {
        let text = "";
        let (mentions, hashtags) = parse(text);

        assert_eq!(mentions.len(), 0);
        assert_eq!(hashtags.len(), 0);
    }

    #[test]
    fn test_no_mentions_or_hashtags() {
        let text = "Just plain text without any mentions or hashtags.";
        let (mentions, hashtags) = parse(text);

        assert_eq!(mentions.len(), 0);
        assert_eq!(hashtags.len(), 0);
    }
}
