use tavern::{Adventurer, Tale};

use dioxus::prelude::*;

use crate::page::Page;
use crate::settings::BardSettings;
use crate::server::*;
use super::tags::*;



#[component]
pub fn BlogAuthor() -> Element
{
   rsx!
   {
      section
      {
         class: "blog_author_style",
      }
   }
}


#[component]
pub fn PostHeaderAuthor(author: Option<Adventurer>, publish_date: String) -> Element
{
   match author
   {
      Some(adventurer) =>
      {
         rsx!
         {
            document::Meta
            {
               name: "author",
               content: "{adventurer.name}"
            }

            i
            {
               "Published: {publish_date}"
            }

            p
            {
               b
               {
                  "Author: ",
                  a { href: "{adventurer.legend.profile}", "{adventurer.name}" }
               }
            }
         }
      }

      None=>
      {
         rsx!
         {
            document::Meta
            {
               name: "author",
               content: "Unknown"
            }

            i
            {
               "Published: {publish_date}"
            }

            p
            {
               b
               {
                  "Author: Unknown"
               }
            }
         }
      }
   }
}

#[component]
pub fn PostHeader(tale: Tale, adventurer: Option<Adventurer>) -> Element
{
   // Get the pages URL.
   let url: Page = use_route();

   // Get the blog's image to use as a placeholder if there isn't one for the
   // blog post.
   // Retrieve the provided settings from context.
   let settings = use_context::<BardSettings>();

   rsx!
   {
      // Open Graph (used by LinkedIn, Bluesky, Discord, etc.)
      document::Meta { property: "og:locale", content: "en_US" }
      document::Meta { name: "title", property: "og:title", content: "{tale.lore.title}" }
      document::Meta { name: "description", property: "og:description", content: "{tale.lore.summary}" }
      document::Meta { property: "og:type", content: "article" }
      document::Meta { property: "og:url", content: "{url}" }
      if let Some(image) = settings.default_post_image
      {
         document::Meta { name: "image", property: "og:image", content: "{image}" }
      }

      h1 { {tale.lore.title} }

      TagList
      {
         for tag in tale.lore.tags
         {
            TagItem
            {
               tag: tag.clone()
            }
         }
      }

      PostHeaderAuthor
      {
         author: adventurer,
         publish_date: tale.lore.publish_date.format("%m/%d/%Y").to_string()
      }
   }
}

#[component]
pub fn Story(text: String) -> Element
{
   use_effect(||
   {
      spawn(async
      {
         document::eval("hljs.highlightAll();")
            .await
            .expect("Error highlighting code");
      });
   });

   rsx!
   {
      div
      {
         class: "blog_post_tale",

         dangerous_inner_html: "{text}"
      }
   }
}

#[component]
pub fn BlogPost(slug: Signal<String>, children: Element) -> Element
{
   // Run a once off server fetch of the unchanging blog data.
   let post_future = use_server_future(move ||
   {
      // Make this reactive so that as the page changes it should rerun this.
      let url_slug = slug();

      async move
      {
         let post = get_blog_post(url_slug).await?;
         let author = get_author(post.lore.author.clone()).await?;
         Ok::<_, ServerFnError>((post, author))
      }
   })?;

   rsx!
   {
      article
      {
         class: "blog_post",

         if let Some(Ok((tale, adventurer))) = (post_future.value())()
         {
            PostHeader
            {
               tale: tale.clone(),
               adventurer: adventurer.clone()
            }

            Story { text: tale.story }


            //Author {}
         }
         else if let Some(Err(e)) = (post_future.value())()
         {
            p { "Unable to load desired post: {slug.read()}" }
            p { "{e}" }
         }
         else
         {
            p { "Loading..." }
         }

         {children}
      }
   }
}

#[component]
pub fn TagNav() -> Element
{
   let tags = use_server_future(move || async move { get_tags().await })?;

   rsx!
   {
      section
      {
         class: "blog_nav",

         fieldset
         {
            class: "tag_list",

            legend { "Category Filter" }

            if let Some(Ok(categories)) = &*tags.read()
            {
               TagList
               {
                  for tag in categories
                  {
                     TagItem
                     {
                        tag: tag.clone()
                     }
                  }
               }
            }
            else if let Some(Err(e)) = &*tags.read()
            {
               p { "Unable to load tags." }
               p { "{e}" }
            }
            else
            {
               p { "Loading..." }
            }
         }
      }
   }
}
