defmodule Blogex.Components do
  @moduledoc """
  Phoenix function components for rendering blog content.

  These are unstyled building blocks — the host app wraps them
  in its own layout and applies its own CSS.

  ## Usage in a LiveView or template:

      import Blogex.Components

      <.post_index blog={@blog_module} posts={@posts} />
      <.post_show post={@post} />
      <.tag_list tags={@tags} base_path={@base_path} />
  """

  use Phoenix.Component

  @doc """
  Renders a list of post previews.

  ## Attributes

    * `:posts` - list of `%Blogex.Post{}` structs (required)
    * `:base_path` - base URL path for post links (required)
    * `:current_tag` - currently selected tag for highlighting (optional)
  """
  attr :posts, :list, required: true
  attr :base_path, :string, required: true
  attr :current_tag, :string, default: nil

  def post_index(assigns) do
    ~H"""
    <div class="blogex-post-index">
      <article :for={post <- @posts} class="blogex-post-preview">
        <header>
          <h2>
            <a href={"#{@base_path}/#{post.id}"}>{post.title}</a>
          </h2>
          <.post_meta post={post} base_path={@base_path} current_tag={@current_tag} />
        </header>
        <p class="blogex-post-description">{post.description}</p>
      </article>
    </div>
    """
  end

  @doc """
  Renders a full blog post.

  ## Attributes

    * `:post` - a `%Blogex.Post{}` struct (required)
    * `:base_path` - base URL path for tag links (required)
  """
  attr :post, :map, required: true
  attr :base_path, :string, required: true

  def post_show(assigns) do
    ~H"""
    <article class="blogex-post">
      <header class="blogex-post-header">
        <h1>{@post.title}</h1>
        <.post_meta post={@post} base_path={@base_path} />
      </header>
      <div class="blogex-post-body">
        {Phoenix.HTML.raw(@post.body)}
      </div>
    </article>
    """
  end

  @doc """
  Renders post metadata (date, author, tags).

  ## Attributes

    * `:post` - a `%Blogex.Post{}` struct (required)
    * `:base_path` - base URL path for tag links (required)
    * `:current_tag` - currently selected tag for highlighting (optional)
  """
  attr :post, :map, required: true
  attr :base_path, :string, required: true
  attr :current_tag, :string, default: nil

  def post_meta(assigns) do
    ~H"""
    <div class="blogex-post-meta">
      <time datetime={Date.to_iso8601(@post.date)}>
        {Calendar.strftime(@post.date, "%B %d, %Y")}
      </time>
      <span :if={@post.author} class="blogex-post-author">
        by {@post.author}
      </span>
      <a
        :for={tag <- @post.tags}
        href={"#{@base_path}/tag/#{tag}"}
        class={["blogex-tag-link", tag == @current_tag && "blogex-tag-active"]}
      >
        {tag}
      </a>
    </div>
    """
  end

  @doc """
  Renders a tag cloud / tag list with links.

  ## Attributes

    * `:tags` - list of tag strings (required)
    * `:base_path` - base URL path (required)
    * `:current_tag` - currently selected tag for highlighting (optional)
  """
  attr :tags, :list, required: true
  attr :base_path, :string, required: true
  attr :current_tag, :string, default: nil

  def tag_list(assigns) do
    ~H"""
    <nav class="blogex-tag-list">
      <a
        :for={tag <- @tags}
        href={"#{@base_path}/tag/#{tag}"}
        class={["blogex-tag-link", tag == @current_tag && "blogex-tag-active"]}
      >
        {tag}
      </a>
    </nav>
    """
  end

  @doc """
  Renders pagination controls.

  ## Attributes

    * `:page` - current page number (required)
    * `:total_pages` - total number of pages (required)
    * `:base_path` - base URL path (required)
  """
  attr :page, :integer, required: true
  attr :total_pages, :integer, required: true
  attr :base_path, :string, required: true

  def pagination(assigns) do
    ~H"""
    <nav :if={@total_pages > 1} class="blogex-pagination">
      <a
        :if={@page > 1}
        href={"#{@base_path}?page=#{@page - 1}"}
        class="blogex-pagination-prev"
      >
        &larr; Newer
      </a>
      <span class="blogex-pagination-info">
        Page {@page} of {@total_pages}
      </span>
      <a
        :if={@page < @total_pages}
        href={"#{@base_path}?page=#{@page + 1}"}
        class="blogex-pagination-next"
      >
        Older &rarr;
      </a>
    </nav>
    """
  end
end
