defmodule FirehoseWeb.BlogController do
  use FirehoseWeb, :controller

  plug :resolve_blog

  def index(conn, params) do
    blog = conn.assigns.blog
    page = parse_page(params["page"])
    result = blog.paginate(page)

    meta = Blogex.SEO.meta_tags_for_blog(blog, FirehoseWeb.Endpoint.url())
    rss_url = rss_feed_url(blog)

    conn
    |> FirehoseWeb.Layouts.put_content_for(:meta_tags, meta)
    |> FirehoseWeb.Layouts.put_content_for(:feed_links, %{rss_url: rss_url, title: blog.title()})
    |> render(:index,
      page_title: blog.title(),
      blog_title: blog.title(),
      blog_description: blog.description(),
      posts: result.entries,
      base_path: blog.base_path(),
      page: result.page,
      total_pages: result.total_pages,
      rss_feed_url: rss_url
    )
  end

  def show(conn, %{"slug" => slug}) do
    blog = conn.assigns.blog
    post = blog.get_post!(slug)
    visibility = Blogex.Post.visibility(post)
    rss_url = rss_feed_url(blog)

    meta = Blogex.SEO.meta_tags(post, FirehoseWeb.Endpoint.url(), blog)

    conn
    |> FirehoseWeb.Layouts.put_content_for(:meta_tags, meta)
    |> FirehoseWeb.Layouts.put_content_for(:feed_links, %{rss_url: rss_url, title: blog.title()})
    |> render(:show,
      page_title: post.title,
      post: post,
      meta: meta,
      base_path: blog.base_path(),
      visibility: visibility,
      authenticated: !!(conn.assigns[:current_scope] && conn.assigns.current_scope.user),
      rss_feed_url: rss_url
    )
  end

  def tag(conn, %{"tag" => tag}) do
    blog = conn.assigns.blog
    posts = blog.posts_by_tag(tag)
    rss_url = rss_feed_url(blog)

    rss_link = %{rss_url: rss_url, title: blog.title()}

    conn
    |> FirehoseWeb.Layouts.put_content_for(:feed_links, rss_link)
    |> render(:tag,
      page_title: "#{blog.title()} — #{tag}",
      blog_title: blog.title(),
      tag: tag,
      posts: posts,
      base_path: blog.base_path(),
      rss_feed_url: rss_url
    )
  end

  defp resolve_blog(%{params: %{"blog_id" => "engineering"}} = conn, _opts),
    do: assign(conn, :blog, Firehose.EngineeringBlog)

  defp resolve_blog(%{params: %{"blog_id" => "releases"}} = conn, _opts),
    do: assign(conn, :blog, Firehose.ReleaseNotes)

  defp resolve_blog(conn, _opts) do
    conn
    |> put_status(:not_found)
    |> put_view(FirehoseWeb.ErrorHTML)
    |> render(:"404")
    |> halt()
  end

  defp parse_page(nil), do: 1

  defp parse_page(str) do
    case Integer.parse(str) do
      {page, ""} when page > 0 -> page
      _ -> 1
    end
  end

  defp rss_feed_url(blog) do
    base_id = blog.base_path() |> String.trim_leading("/blog/")
    FirehoseWeb.Endpoint.url() <> "/api/blog/#{base_id}/feed.xml"
  end
end
