class Post < ApplicationRecord
  require 'mini_magick'

  belongs_to :parent, class_name: 'Post', optional: true, foreign_key: 'parent_id'
  belongs_to :uploaded_user, class_name: 'User', optional: true

  has_many :post_tags, dependent: :destroy, inverse_of: :post
  has_many :active_post_tags, -> { kept }, class_name: 'PostTag', inverse_of: :post
  has_many :post_tags_with_discarded, -> { with_discarded }, class_name: 'PostTag'
  has_many :tags, through: :active_post_tags
  has_many :user_post_views, dependent: :destroy
  has_many :post_similarities_as_post,
           class_name: 'PostSimilarity',
           foreign_key: :post_id
  has_many :post_similarities_as_target_post,
           class_name: 'PostSimilarity',
           foreign_key: :target_post_id
  has_one_attached :thumbnail

  validate :validate_original_created_range

  def as_json options = { }
    super(options).merge({ thumbnail: thumbnail.attached? ?
                                      Rails.application.routes.url_helpers.rails_blob_url(
                                          thumbnail, only_path: false) :
                                      nil })
  rescue
    super(options).merge(thumbnail: nil)
  end

  def related(limit: nil)
    ids_with_cos =
        post_similarities_as_post.select(:target_post_id, :cos)
                                 .map { |ps| [ps.target_post_id, ps.cos] } +
        post_similarities_as_target_post.select(:post_id, :cos)
                                        .map { |ps| [ps.post_id, ps.cos] }

    sorted = ids_with_cos.sort_by { |_, cos| -cos }

    ids = sorted.map(&:first)
    ids = ids.first(limit) if limit

    Post.where(id: ids).index_by(&:id).values_at(*ids)
  end

  def resized_thumbnail!
    return unless thumbnail.attached?

    image = MiniMagick::Image.read(thumbnail.download)
    image.resize '180x180'
    thumbnail.purge
    thumbnail.attach(io:            File.open(image.path),
                     filename:      'resized_thumbnail.jpg',
                     content_type:  'image/jpeg')
  end

  private

  def validate_original_created_range
    f = original_created_from
    b = original_created_before
    return if f.blank? || b.blank?

    f = Time.zone.parse(f) if String === f
    b = Time.zone.parse(b) if String === b
    return if !(f) || !(b)

    if f >= b
      errors.add :original_created_before, 'オリジナルの作成日時の順番がをかしぃです．'
    end
  end
end
