# frozen_string_literal: true


module PostRepr
  BASE_FIELDS = [
      :id,
      :version_no,
      :url,
      :title,
      :thumbnail_base,
      :video_ms,
      :original_created_from,
      :original_created_before,
      :created_at,
      :updated_at
  ].freeze

  module_function

  def base post, current_user = nil, host: nil
    json =
        if host.present?
          common(post, host:)
        else
          common(post)
        end
    json['tags'] = tag_json(post)
    json['uploaded_user'] = post.uploaded_user && UserRepr.base(post.uploaded_user)
    json['viewed'] = current_user ? current_user.viewed?(post) : false
    json
  end

  def detail post, current_user = nil, parent_posts: [], child_posts: [],
             sibling_posts: { }, related: [], host: nil
    if host.present?
      base(post, current_user, host:).merge(
          'parent_posts' => cards(parent_posts, host:),
          'child_posts' => cards(child_posts, host:),
          'sibling_posts' => sibling_posts.transform_keys(&:to_s).transform_values { |posts|
            cards(posts, host:)
          },
          'related' => cards(related, host:))
    else
      base(post, current_user).merge(
          'parent_posts' => cards(parent_posts),
          'child_posts' => cards(child_posts),
          'sibling_posts' => sibling_posts.transform_keys(&:to_s).transform_values { |posts|
            cards(posts)
          },
          'related' => cards(related))
    end
  end

  def card post, host: nil
    if host.present?
      common(post, host:).merge('parent_posts' => [], 'child_posts' => [])
    else
      common(post).merge('parent_posts' => [], 'child_posts' => [])
    end
  end

  def cards posts, host: nil
    if host.present?
      posts.map { |post| card(post, host:) }
    else
      posts.map { |post| card(post) }
    end
  end

  def many posts, current_user = nil, host: nil
    if host.present?
      posts.map { |p| base(p, current_user, host:) }
    else
      posts.map { |p| base(p, current_user) }
    end
  end

  def common post, host: nil
    BASE_FIELDS.to_h { |field| [field.to_s, post.public_send(field)] }
               .merge(
                   'thumbnail' =>
                       if host.present?
                         thumbnail_url(post, host:)
                       else
                         thumbnail_url(post)
                       end)
  end

  def tag_json post
    post
        .active_post_tags
        .reject { _1.tag.deprecated? }
        .sort_by { _1.tag.name }
        .map { |post_tag|
      TagRepr.inline(post_tag.tag).merge(
          'children' => [],
          'sections' => post_tag.sections.as_json(only: [:begin_ms, :end_ms]))
    }
  end

  def thumbnail_url post, host: nil
    return nil unless post.thumbnail.attached?

    options = { only_path: false }
    options[:host] = host if host.present?

    Rails.application.routes.url_helpers.rails_storage_proxy_url(post.thumbnail, **options)
  rescue ActionController::UrlGenerationError, ArgumentError, URI::InvalidURIError => e
    payload = {
        post_id: post.id,
        attachment_id: post.thumbnail.attachment&.id,
        blob_id: post.thumbnail.blob&.id,
        error_class: e.class,
        message: e.message }

    Rails.logger.warn("PostRepr.thumbnail_url failed #{ payload.to_json }")
    nil
  end
end
