# frozen_string_literal: true

require 'rails_helper'

feature 'User managing appearance releases' do
  let(:current_user) { create(:user, :manager) }
  let(:project) { create(:project, members: current_user, account: current_user.primary_account) }

  context 'when signed out' do
    scenario 'creating a release for an adult', js: true do
      allow(BrayniacAI::Validation).to receive(:create).and_return(double(:validation, valid: true))

      project = create(:project, members: current_user, account: current_user.primary_account)
      contract_template = create(:contract_template, project: project)

      visit new_account_project_contract_template_appearance_release_path(project.account, project, contract_template)

      expect(page).to have_photo_button

      fill_in person_first_name_field, with: 'Jane'
      fill_in person_last_name_field, with: 'Doe'
      fill_in person_address_field, with: '123 Test Lane, New York, NY 10000'
      fill_in person_phone_field, with: '555-555-5555'
      fill_in person_email_field, with: 'jane.doe@test.com'
      fill_in person_date_of_birth, with: '01/01/1999'
      attach_file person_photo_field, file_fixture('person_photo.png'), visible: :all
      draw_signature file_fixture('signature.png'), 'appearance_release_signature_base64'
      click_button submit_release_button

      expect(page).to have_content(successful_submission_message)
    end

    scenario 'creating a release for a minor', js: true do
      allow(BrayniacAI::Validation).to receive(:create).and_return(double(:validation, valid: true))

      project = create(:project, members: current_user, account: current_user.primary_account)
      contract_template = create(:contract_template, project: project)

      visit new_account_project_contract_template_appearance_release_path(project.account, project, contract_template)

      expect(page).to have_photo_button
      expect(page).not_to have_content('GUARDIAN INFORMATION')
      expect(page).not_to have_content('GUARDIAN PHOTO')

      page.check person_is_minor_checkbox
      expect(page).to have_content('GUARDIAN INFORMATION')
      expect(page).to have_content('GUARDIAN PHOTO')
      expect(page).to have_content 'Guardian Email'

      fill_in guardian_first_name_field, with: 'Guardian'
      fill_in guardian_last_name_field, with: 'Name'
      fill_in guardian_phone_field, with: '001101'
      fill_in person_first_name_field, with: 'Jane'
      fill_in person_last_name_field, with: 'Doe'
      fill_in person_address_field, with: '123 Test Lane, New York, NY 10000'
      fill_in person_phone_field, with: '555-555-5555'
      fill_in person_email_field, with: 'jane.doe@test.com'
      fill_in person_date_of_birth, with: '01/01/1999'
      attach_file person_photo_field, file_fixture('person_photo.png'), visible: :all
      attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
      draw_signature file_fixture('signature.png'), 'appearance_release_signature_base64'

      fill_in guardian_email_field, with: 'invalid@email'
      click_button submit_release_button
      expect(page).to have_content('Guardian email is not an email')

      fill_in guardian_email_field, with: 'valid@email.com'
      fill_in guardian_address_field, with: '123 Test Lane, New York, NY 10000'
      attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
      draw_signature file_fixture('signature.png'), 'appearance_release_signature_base64'
      click_button submit_release_button

      expect(page).to have_content(successful_submission_message)
    end
  end

  context 'when signed in' do
    before :each do
      sign_in current_user
    end

    scenario 'editing non native release for adult', js: true do
      appearance_release = create(:appearance_release, :non_native, project: project)

      visit edit_appearance_release_path(appearance_release)

      expect(page).not_to have_content('Guardian Photo')

      by 'filling out the form' do
        fill_in person_first_name_field, with: 'New John'
        fill_in person_last_name_field, with: 'Doe'
        fill_in person_email_field, with: 'john.doe@test.com'
        select 'Other', from: 'Applicable Media'
        fill_in 'Describe other applicable media', with: 'Test'
        select 'Other', from: 'Territory'
        fill_in 'Describe other territory', with: 'Test'
        select 'Other', from: 'Term'
        fill_in 'Describe other term', with: 'Test'
        select 'Other', from: 'Restriction'
        fill_in 'Describe other restrictions', with: 'Test'
      end

      click_button submit_update_button

      expect(page).to have_content successful_update_message
      expect(page).to have_content 'New John'
    end

    scenario 'editing non native release for minor', js: true do
      appearance_release = create(:appearance_release, :non_native, :minor, project: project)

      visit edit_appearance_release_path(appearance_release)

      expect(page).to have_content('Guardian Photo')

      by 'filling out the form' do
        page.check person_is_minor_checkbox
        fill_in guardian_first_name_field, with: 'Guardian'
        fill_in guardian_last_name_field, with: 'Name'
        fill_in guardian_phone_field, with: '00101'
        fill_in person_first_name_field, with: 'New Jane'
        fill_in person_last_name_field, with: 'Doe'
        fill_in person_email_field, with: 'jane.doe@test.com'
        select 'Other', from: 'Applicable Media'
        fill_in 'Describe other applicable media', with: 'Test'
        select 'Other', from: 'Territory'
        fill_in 'Describe other territory', with: 'Test'
        select 'Other', from: 'Term'
        fill_in 'Describe other term', with: 'Test'
        select 'Other', from: 'Restriction'
        fill_in 'Describe other restrictions', with: 'Test'
      end

      expect(page).to have_content 'Guardian Photo'

      click_button submit_update_button

      expect(page).to have_content successful_update_message
      expect(page).to have_content 'New Jane'
    end

    scenario 'progress bar shows when user imports a release', js: true do
      visit project_appearance_releases_path(project)

      expect(page).not_to have_css('#upload-progress-container')
      large_pdf_file = build_large_pdf_file
      attach_file import_appearance_release_field, Rails.root.join(large_pdf_file.path), visible: false
      expect(page).to have_css('#upload-progress-container')
      expect(page).to have_content submit_create_button, wait: 30 
      click_button submit_create_button
      expect(page).to have_content matching_started
    end

    scenario 'MatchAppearanceReleasesJob is started when import is finished', js: true do
      visit project_appearance_releases_path(project)

      attach_file import_appearance_release_field, Rails.root.join(file_fixture('person_photo.png')), visible: false
      allow(MatchAppearanceReleasesJob).to receive(:perform_later).with(project, anything)
      click_button submit_create_button
      expect(page).to have_content matching_started
      visit project_appearance_releases_path(project)
      expect(page).to have_content no_appearance_releases
    end

    scenario 'user leaving the page is presented with the warning if file upload is in progress', js: true do
      skip "Test is inconsistently failing in CI"

      visit project_appearance_releases_path(project)

      expect(page).to have_content submit_create_button
      expect(page).to have_content no_appearance_releases

      large_pdf_file = build_large_pdf_file
      attach_file import_appearance_release_field, Rails.root.join(large_pdf_file.path), visible: false

      page.dismiss_confirm do
        first('a', text: 'Files').click
      end

      expect(page).to have_content importing_label
      # Here capybara automatically waits and submit button changes label from Importing... to Import Release again
      expect(page).to have_content submit_create_button

      first('a', text: 'Files').click
      expect(page).not_to have_content no_appearance_releases
    end

    scenario 'updating a release' do
      appearance_release = create(:appearance_release, :non_native, project: project)

      visit edit_appearance_release_path(appearance_release)

      fill_in person_first_name_field, with: 'New'
      fill_in person_last_name_field, with: 'Name'
      click_button submit_update_button

      expect(page).to have_content(successful_update_message)
      expect(page).to have_content('New Name')
    end

    scenario 'viewing the contract PDF' do
      appearance_release = create(:appearance_release_with_contract_template,
                                  :native,
                                  project: project,
                                  person_first_name: 'Jane',
                                  person_last_name: 'Doe',
                                  tag_list: 'Woman, Brunette',
                                  notes: [
                                    build(:note,
                                          content: 'Note 1',
                                          user: build(:user, email: 'jane.doe@test.com'),
                                          email: 'jane.doe@test.com',
                                          created_at: DateTime.new(2020, 2, 21, 12, 0, 0)),
                                    build(:note,
                                          content: 'Note 2',
                                          user: build(:user, email: 'john.doe@test.com'),
                                          email: 'john.doe@test.com',
                                          created_at: DateTime.new(2020, 2, 20, 11, 0, 0))
                                  ])

      sign_in(current_user)
      visit project_appearance_releases_path(project)
      click_link *view_release_pdf_link_for(appearance_release)

      expect(content_type).to eq('application/pdf')
      expect(content_disposition).to include('inline')
      expect(pdf_filename).to include('doe-jane')
      expect(pdf_body).to have_content('Jane Doe')
      expect(pdf_body).to have_content('NOTES')
      expect(pdf_body).to have_content('Note 1')
      expect(pdf_body).to have_content('jane.doe@test.com')
      expect(pdf_body).to have_content('2/21/20 12:00 PM')
      expect(pdf_body).to have_content('Note 2')
      expect(pdf_body).to have_content('john.doe@test.com')
      expect(pdf_body).to have_content('2/20/20 11:00 AM')
      expect(pdf_body).to have_content('TAGS')
      expect(pdf_body).to have_content('Woman')
      expect(pdf_body).to have_content('Brunette')
      expect(pdf_body).not_to have_content('Guardian Email')
    end

    scenario 'viewing contract PDF for a minor without guardian photo' do
      appearance_release = create(:appearance_release_with_contract_template, :native, :minor, project: project)

      visit project_appearance_releases_path(project)
      click_link *view_release_pdf_link_for(appearance_release)

      expect(content_type).to eq('application/pdf')
      expect(content_disposition).to include('inline')
      expect(pdf_filename).to include(appearance_release.filename_suffix.parameterize)
      expect(pdf_body).to have_content(appearance_release.name)
      expect(pdf_body).to have_content(appearance_release.guardian_name)
      expect(pdf_body).to have_content(appearance_release.guardian_email)
      expect(pdf_body).to have_content photos_heading.upcase
      expect(pdf_body).to have_content(appearance_release.photo.filename.to_s)
      expect(pdf_body).to have_content('Guardian Email')
    end

    scenario 'viewing contract PDF for a minor with guardian photo' do
      appearance_release = create(:appearance_release_with_contract_template, :native, :minor_with_guardian_photo, project: project)

      visit project_appearance_releases_path(project)
      click_link *view_release_pdf_link_for(appearance_release)

      expect(content_type).to eq('application/pdf')
      expect(content_disposition).to include('inline')
      expect(pdf_filename).to include(appearance_release.filename_suffix.parameterize)
      expect(pdf_body).to have_content(appearance_release.name)
      expect(pdf_body).to have_content(appearance_release.guardian_name)
      expect(pdf_body).to have_content(appearance_release.guardian_email)
      expect(pdf_body).to have_content photos_heading(2).upcase
      expect(pdf_body).to have_content(appearance_release.photo.filename.to_s)
      expect(pdf_body).to have_content(appearance_release.guardian_photo.filename.to_s)
      expect(pdf_body).to have_content('Guardian Email')
    end

    scenario 'deleting a release', js: true do
      appearance_release = create(:appearance_release, project: project)

      visit project_appearance_releases_path(project)

      click_on 'Manage'
      accept_alert do
        click_link *destroy_link_for(appearance_release)
      end

      expect(page).to have_content(successful_destroy_message)
    end

    scenario 'searching for a release', js: true do
      chris = create(:appearance_release, person_first_name: 'Chris', person_last_name: 'Evans', project: project)
      robert = create(:appearance_release, person_first_name: 'Robert', person_last_name: 'Downey Jr.', project: project)

      visit project_appearance_releases_path(project)

      expect(page).to have_content('Chris Evans')
      expect(page).to have_content('Robert Downey Jr.')

      within 'form#search' do
        fill_in 'Search', with: 'Robert'
        click_on 'button'
      end

      expect(page).to have_content('Robert Downey Jr.')
      expect(page).not_to have_content('Chris Evans')
      expect(page).to have_field('Search', with: 'Robert')
    end

    scenario 'filtering for a release by complete/incomplete type', js: true do
      create(:appearance_release, :without_person_photo, :non_native, person_first_name: 'Chris', person_last_name: 'Evans Incomplete', project: project)
      create(:appearance_release, :non_native, person_first_name: 'Chris', person_last_name: 'Evans Complete', project: project)
      create(:appearance_release, :without_person_photo, :non_native, person_first_name: 'Robert', person_last_name: 'Downey Jr. Incomplete', project: project)
      create(:appearance_release, :non_native, person_first_name: 'Robert', person_last_name: 'Downey Jr. Complete', project: project)

      visit project_appearance_releases_path(project)

      expect(page).to have_content('Chris Evans Incomplete')
      expect(page).to have_content('Chris Evans Complete')
      expect(page).to have_content('Robert Downey Jr. Incomplete')
      expect(page).to have_content('Robert Downey Jr. Complete')

      click_link filter_type_complete

      expect(page).not_to have_content('Chris Evans Incomplete')
      expect(page).to have_content('Chris Evans Complete')
      expect(page).not_to have_content('Robert Downey Jr. Incomplete')
      expect(page).to have_content('Robert Downey Jr. Complete')

      click_link filter_type_incomplete

      expect(page).to have_content('Chris Evans Incomplete')
      expect(page).not_to have_content('Chris Evans Complete')
      expect(page).to have_content('Robert Downey Jr. Incomplete')
      expect(page).not_to have_content('Robert Downey Jr. Complete')

      click_link filter_type_all

      expect(page).to have_content('Chris Evans Incomplete')
      expect(page).to have_content('Chris Evans Complete')
      expect(page).to have_content('Robert Downey Jr. Incomplete')
      expect(page).to have_content('Robert Downey Jr. Complete')
    end

    scenario 'filtering for a release by complete/incomplete type works in parallel with search', js: true do
      create(:appearance_release, :without_person_photo, :non_native, person_first_name: 'Chris', person_last_name: 'Evans Incomplete', project: project)
      create(:appearance_release, :non_native, person_first_name: 'Chris', person_last_name: 'Evans Complete', project: project)
      create(:appearance_release, :without_person_photo, :non_native, person_first_name: 'Robert', person_last_name: 'Downey Jr. Incomplete', project: project)
      create(:appearance_release, :non_native, person_first_name: 'Robert', person_last_name: 'Downey Jr. Complete', project: project)

      visit project_appearance_releases_path(project)

      expect(page).to have_content('Chris Evans Incomplete')
      expect(page).to have_content('Chris Evans Complete')
      expect(page).to have_content('Robert Downey Jr. Incomplete')
      expect(page).to have_content('Robert Downey Jr. Complete')

      click_link filter_type_complete

      expect(page).not_to have_content('Chris Evans Incomplete')
      expect(page).to have_content('Chris Evans Complete')
      expect(page).not_to have_content('Robert Downey Jr. Incomplete')
      expect(page).to have_content('Robert Downey Jr. Complete')

      within 'form#search' do
        fill_in 'Search', with: 'Robert'
        click_on 'button'
      end

      expect(page).not_to have_content('Chris Evans Incomplete')
      expect(page).not_to have_content('Chris Evans Complete')
      expect(page).not_to have_content('Robert Downey Jr. Incomplete')
      expect(page).to have_content('Robert Downey Jr. Complete')

      click_link filter_type_incomplete

      expect(page).not_to have_content('Chris Evans Incomplete')
      expect(page).not_to have_content('Chris Evans Complete')
      expect(page).to have_content('Robert Downey Jr. Incomplete')
      expect(page).not_to have_content('Robert Downey Jr. Complete')

      click_link filter_type_all

      expect(page).not_to have_content('Chris Evans Incomplete')
      expect(page).not_to have_content('Chris Evans Complete')
      expect(page).to have_content('Robert Downey Jr. Incomplete')
      expect(page).to have_content('Robert Downey Jr. Complete')
    end
  end

  context 'when the user is associate' do
    let(:current_user) { create(:user, :associate) }

    scenario 'should not show download' do
      chris = create(:appearance_release_with_contract_template, person_first_name: 'Chris', person_last_name: 'Evans', project: project)

      sign_in current_user
      visit project_appearance_releases_path(project)

      click_on 'Manage'
      expect(page).not_to have_link('Download', exact: true)
    end
  end

  private

  def build_large_pdf_file
    # Generates dummy temp file with approx 50MB
    tempfile = Tempfile.new(['large_file', '.pdf'], Rails.root.join('tmp'))
    tempfile << '%PDF-1.2'
    1_000_000.times do
      tempfile << 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
    end
    tempfile << '%%EOF'
    tempfile
  end

  def matching_started
    t 'appearance_releases.create.matching_started'
  end

  def filter_type_all
    t 'appearance_releases.type_filter_actions.all_releases'
  end

  def filter_type_complete
    t 'appearance_releases.type_filter_actions.complete_releases'
  end

  def filter_type_incomplete
    t 'appearance_releases.type_filter_actions.incomplete_releases'
  end

  def failed_to_import_notice
    t 'appearance_releases.create.failed_import'
  end

  def importing_label
    'Importing...'
  end

  def no_appearance_releases
    t 'appearance_releases.index.empty'
  end

  def photos_heading(photos_count = 1)
    t 'contracts.photos.heading', count: photos_count
  end

  def have_photo_button
    have_selector('.take-photo-button')
  end

  def person_is_minor_checkbox
    'appearance_release_minor'
  end

  def guardian_first_name_field
    'Guardian first name'
  end

  def guardian_last_name_field
    'Guardian last name'
  end

  def guardian_phone_field
    'Guardian phone'
  end

  def guardian_email_field
    'Guardian email'
  end

  def guardian_address_field
    'Guardian address'
  end

  def guardian_photo_field
    'appearance_release[guardian_photo]'
  end

  def person_name_field
    t('helpers.label.appearance_release.person_name')
  end

  def person_first_name_field
    t('helpers.label.appearance_release.person_first_name')
  end

  def person_last_name_field
    t('helpers.label.appearance_release.person_last_name')
  end

  def person_address_field
    t('helpers.label.appearance_release.person_address')
  end

  def person_email_field
    t('helpers.label.appearance_release.person_email')
  end

  def person_phone_field
    t('helpers.label.appearance_release.person_phone')
  end

  def import_appearance_release_field
    'attachments[]'
  end

  def person_photo_field
    'appearance_release[person_photo]'
  end

  def contract_field
    'appearance_release[contract]'
  end

  def person_date_of_birth
    'appearance_release[person_date_of_birth]'
  end

  def submit_create_button
    'Import Release'
  end

  def submit_release_button
    'I have read and agree to the above'
  end

  def submit_update_button
    'Save Changes'
  end

  def edit_link_for(appearance_release)
    ['Edit', href: edit_appearance_release_path(appearance_release)]
  end

  def destroy_link_for(appearance_release)
    ['Delete', href: appearance_release_path(appearance_release)]
  end

  def view_release_pdf_link_for(appearance_release)
    ['Download', href: appearance_release_contracts_path(appearance_release, format: 'pdf')]
  end

  def successful_submission_message
    'Your release was successfully submitted. Thank you.'
  end

  def succesful_create_message
    'The release has been imported.'
  end

  def successful_update_message
    'The release has been updated'
  end

  def successful_destroy_message
    'The release has been deleted'
  end
end
