# typed: false
require "rails_helper"

describe Domain::E621::Job::ScanPostFavsJob do
  let(:http_client_mock) { instance_double("::Scraper::HttpClient") }
  before { Scraper::ClientFactory.http_client_mock = http_client_mock }
  before do
    e621_user_ids = [
      454_589,
      1_535_298,
      956_950,
      413_725,
      372_696,
      940_693,
      2_055_406,
      1_775_383,
      954_593,
    ]
    Domain::User::E621User.load_schema
    e621_user_ids.each do |e621_id|
      create(:domain_user_e621_user, e621_id: e621_id)
    end
  end

  it "scans users who favorited the post" do
    post = create(:domain_post_e621_post, e621_id: 4_005_902)
    HttpClientMockHelpers.init_http_client_mock(
      http_client_mock,
      [
        {
          uri: "https://e621.net/posts/4005902/favorites?limit=10&page=1",
          status_code: 200,
          content_type: "text/html",
          contents:
            SpecUtil.read_fixture_file("domain/e621/job/post_favs_0.html"),
        },
        {
          uri: "https://e621.net/posts/4005902/favorites?limit=10&page=2",
          status_code: 200,
          content_type: "text/html",
          contents:
            SpecUtil.read_fixture_file("domain/e621/job/post_favs_1.html"),
          caused_by_entry_idx: 0,
        },
      ],
    )

    expect(post.scanned_post_favs_at).to be_nil
    perform_now({ post: post })
    post.reload

    # Verify post was marked as scanned
    expect(post.scanned_post_favs_at).to be_within(3.seconds).of(Time.now)

    # Verify users were created and updated with correct fav counts
    # First page users
    users_page1 =
      Domain::User::E621User.where(
        e621_id: [454_589, 1_535_298, 956_950, 413_725, 372_696],
      )
    expect(users_page1.count).to eq(5)

    # Check specific user fav counts from first page
    expect(users_page1.find_by(e621_id: 454_589).num_other_favs_cached).to eq(
      765,
    )
    expect(users_page1.find_by(e621_id: 1_535_298).num_other_favs_cached).to eq(
      330,
    )
    expect(users_page1.find_by(e621_id: 956_950).num_other_favs_cached).to eq(
      24,
    )
    expect(users_page1.find_by(e621_id: 413_725).num_other_favs_cached).to eq(
      2529,
    )
    expect(users_page1.find_by(e621_id: 372_696).num_other_favs_cached).to eq(
      88,
    )

    # Second page users
    users_page2 =
      Domain::User::E621User.where(
        e621_id: [940_693, 2_055_406, 1_775_383, 954_593],
      )
    expect(users_page2.count).to eq(4)

    # Check specific user fav counts from second page
    expect(users_page2.find_by(e621_id: 940_693).num_other_favs_cached).to eq(
      25_685,
    )
    expect(users_page2.find_by(e621_id: 2_055_406).num_other_favs_cached).to eq(
      37,
    )
    expect(users_page2.find_by(e621_id: 1_775_383).num_other_favs_cached).to eq(
      497,
    )
    expect(users_page2.find_by(e621_id: 954_593).num_other_favs_cached).to eq(
      70,
    )
  end

  it "handles error responses" do
    post = create(:domain_post_e621_post, e621_id: 4_005_902)
    HttpClientMockHelpers.init_http_client_mock(
      http_client_mock,
      [
        {
          uri: "https://e621.net/posts/4005902/favorites?limit=10&page=1",
          status_code: 404,
          content_type: "text/html",
          contents: "Not Found",
        },
      ],
    )

    expect { perform_now({ post: post }) }.to raise_error(/404 - bailing/)

    post.reload
    expect(post.scanned_post_favs_at).to be_nil
  end
end
