class GekanatorPostsController < ApplicationController
  def index
    posts =
        Post
        .preload(:post_similarities, tags: :tag_name)
        .with_attached_thumbnail
        .order(Arel.sql(
            'COALESCE(posts.original_created_before - INTERVAL 1 MINUTE, ' \
            'posts.original_created_from, posts.created_at) DESC, posts.id DESC'))
        .to_a

    active_tags_by_post_id =
        posts.each_with_object({ }) do |post, h|
          h[post.id] = post.tags.reject(&:deprecated?)
        end

    render json: {
      posts: posts.map { |post|
        post_json(post,
                  active_tags_by_post_id:)
      }
    }
  end

  private

  def post_json post, active_tags_by_post_id:
    {
      id: post.id,
      url: post.url,
      title: post.title,
      thumbnail: thumbnail_url(post),
      thumbnail_base: post.thumbnail_base,
      original_created_from: post.original_created_from,
      original_created_before: post.original_created_before,
      post_similarity_edges: post_similarity_edges_json(
          post,
          active_tags_by_post_id:),
      tags: active_tags_by_post_id.fetch(post.id, []).map { |tag| tag_json(tag) }
    }
  end

  def post_similarity_edges_json post, active_tags_by_post_id:
    post
        .post_similarities
        .filter_map do |similarity|
          next unless active_tags_by_post_id.key?(similarity.target_post_id)

          {
            target_post_id: similarity.target_post_id,
            cos: similarity.cos.to_f
          }
        end
  end

  def tag_json tag
    {
      id: tag.id,
      name: tag.name,
      category: tag.category
    }
  end

  def thumbnail_url post
    return nil unless post.thumbnail.attached?

    rails_storage_proxy_url(post.thumbnail, only_path: false)
  rescue
    nil
  end
end
