# typed: false
# frozen_string_literal: true
T.bind(self, T.all(Rake::DSL, Object))

namespace :e621 do
  desc "run a single e621 posts index job"
  task posts_index_job: :environment do
    Domain::E621::Job::PostsIndexJob.set(priority: -10).perform_later({})
  end

  desc "download files for posts missing files"
  task download_missing_files: %i[environment set_logger_stdout] do
    relation =
      Domain::Post::E621Post
        .where(file: nil, state: :ok)
        .where.not(file_url_str: nil)
    puts "will download #{relation.count} posts"
    relation.find_each do |p|
      Domain::E621::Job::StaticFileJob.perform_now(post: p)
    end
  end

  desc "scan e621 user favs"
  task scan_user_favs: :environment do
    while user =
            Domain::User::E621User
              .where(scanned_favs_at: nil)
              .where(num_other_favs_cached: ..200)
              .order("RANDOM()")
              .take
      Domain::E621::Job::ScanUserFavsJob.perform_now(user: user)
    end
  end

  desc "scan e621 user favs, descending by num_other_favs_cached"
  task scan_user_favs_descending: %i[environment set_logger_stdout] do
    user_query =
      lambda do
        Domain::User::E621User
          .where(scanned_favs_status: nil)
          .or(Domain::User::E621User.where.not(scanned_favs_status: "error"))
          .where(scanned_favs_at: nil)
          .where.not(num_other_favs_cached: nil)
          .order(num_other_favs_cached: :desc)
      end
    while user = user_query.call.first
      Domain::E621::Job::ScanUserFavsJob.perform_now(user: user)
    end
  end

  desc "Gather cached user fav counts based on post fav lists"
  task collect_post_favs: :environment do
    max_page = (ENV["MAX_PAGE"] || 5).to_i
    start_page = (ENV["START_PAGE"] || 1).to_i
    default_query = "status:any order:favcount"
    query = nil
    while query.blank?
      print "query (#{default_query})> "
      query = $stdin.gets&.chomp || default_query
    end

    Domain::E621::Task::CollectPostFavsTask.new.run(
      query:,
      start_page:,
      max_page:,
    )
  end

  desc "Show statistics about e621 favs"
  task fav_stats: :environment do
    puts "counting total users with cached favs..."
    user_relation = Domain::User::E621User.where.not(num_other_favs_cached: nil)
    total_users = user_relation.count
    puts "total users: #{total_users}"

    puts "counting how many of those users have favs scanned..."
    users_with_favs_scanned =
      user_relation.where.not(scanned_favs_at: nil).count
    puts "users with favs scanned: #{users_with_favs_scanned}"
    puts "percent scanned: #{((users_with_favs_scanned.to_f / total_users.to_f) * 100).round(1)}%"

    puts "counting total cached..."
    total_cached =
      ReduxApplicationRecord.connection.execute(<<~SQL).first["total"]
      select SUM((json_attributes->>'num_other_favs_cached')::int) as total
      from domain_e621_users
    SQL

    puts "counting total have..."
    total_have = Domain::UserPostFav.for_post_type(Domain::Post::E621Post).count

    helper = Class.new.extend(ActionView::Helpers::NumberHelper)
    puts "total cached: #{helper.number_with_delimiter(total_cached)}"
    puts "total have:   #{helper.number_with_delimiter(total_have)}"
    puts "percent cached: #{((total_have.to_f / total_cached.to_f) * 100).round(1)}%"
  end
end
