# typed: strict
class Domain::Sofurry::Job::ScanPostJob < Domain::Sofurry::Job::Base
  include HasBulkEnqueueJobs
  self.default_priority = -10

  sig { override.params(args: T::Hash[Symbol, T.untyped]).returns(T.untyped) }
  def perform(args)
    post = post_from_args!
    logger.push_tags(make_arg_tag(post))
    logger.info(format_tags(make_arg_tag(post)))
    scan_post(post)
  ensure
    post.save! if post
  end

  private

  sig { params(post: Domain::Post::SofurryPost).void }
  def scan_post(post)
    response =
      http_client.get(
        "https://api2.sofurry.com/std/getSubmissionDetails?id=#{post.sofurry_id}",
      )
    post.last_scan_log_entry = response.log_entry

    if response.status_code == 500
      post.state_terminal_error!
      fatal_error(
        "failed to get post details (post removed?): #{response.status_code}",
      )
    elsif response.status_code != 200
      post.state_retryable_error!
      fatal_error("failed to get post details: #{response.status_code}")
    end

    post_details_json = JSON.parse(response.body)
    post.media_type = post_details_json["contentType"]&.to_i
    post.title = post_details_json["title"]
    post.description = post_details_json["description"]
    post.file_name = post_details_json["fileName"]
    post.creator ||=
      Domain::User::SofurryUser.find_or_create_by(
        sofurry_id: post_details_json["authorID"],
      ) { |user| user.username = post_details_json["author"] }

    post.state_ok!
    post.scanned_at = Time.now
    post.save!

    file = post.file
    if file.nil?
      file =
        post.create_file!(
          {
            url_str:
              "https://www.sofurryfiles.com/std/content?page=#{post.sofurry_id}",
          },
        )
    end
    if file.state_pending?
      defer_job(Domain::Sofurry::Job::StaticFileJob, { file: })
    end
  end
end
