require "rails_helper"

feature "User managing medical releases" do
  let(:current_user) { create(:user) }
  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_medical_release_path(project.account, project, contract_template)

      fill_in person_first_name_field, with: 'Jane'
      fill_in person_last_name_field, with: 'Doe'
      fill_in_person_address_fields
      fill_in person_phone_field, with: '555-555-5555'
      fill_in person_email_field, with: 'jane.doe@test.com'
      drop_file Rails.root.join(file_fixture("person_photo.png")), type: :dropzone
      draw_signature file_fixture("signature.png"), "medical_release_signature_base64"

      expect do
        click_button submit_release_button
      end.to change(MedicalRelease, :count).by(1)

      expect(page).to have_content(successful_submission_message)
    end

    scenario "creating a release for a minor - guardian fields are required when minor checkbox is checked", js: true do
      contract_template = create(:contract_template, project: project)

      visit new_account_project_contract_template_medical_release_path(project.account, project, contract_template)

      all('input[data-required-tag="guardian"]').each do |field|
        expect(field['required']).to eq 'false'
        expect(field).not_to be_visible
      end

      page.check person_is_minor_checkbox

      all('input[data-required-tag="guardian"]').each do |field|
        expect(field['required']).to eq 'true'
        expect(field).to be_visible
      end
    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_medical_release_path(project.account, project, contract_template)

      expect(page).not_to have_content guardian_information_heading.upcase
      expect(page).not_to have_content guardian_photo_heading.upcase

      page.check person_is_minor_checkbox
      expect(page).to have_content guardian_information_heading.upcase
      expect(page).to have_content guardian_photo_heading.upcase
      expect(page).to have_content guardian_email_field.titleize

      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 guardian_email_field, with: "valid@email.com"
      fill_in person_first_name_field, with: 'Jane'
      fill_in person_last_name_field, with: 'Doe'
      fill_in_person_address_fields
      fill_in person_phone_field, with: '555-555-5555'
      fill_in person_email_field, with: 'jane.doe@test.com'
      drop_file Rails.root.join(file_fixture("person_photo.png")), type: :dropzone
      attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
      draw_signature file_fixture('signature.png'), 'medical_release_signature_base64'

      fill_in_guardian_address_fields
      attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
      draw_signature file_fixture('signature.png'), 'medical_release_signature_base64'
      click_button submit_release_button

      expect(page).to have_content(successful_submission_message)
    end

    scenario 'creating a release for a minor with two guardians', 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_medical_release_path(project.account, project, contract_template)

      expect(page).not_to have_content guardian_2_information_heading.upcase
      expect(page).not_to have_content guardian_2_photo_heading.upcase

      page.check person_is_minor_checkbox
      expect(page).to have_content guardian_information_heading.upcase
      expect(page).to have_content guardian_photo_heading.upcase
      expect(page).to have_content guardian_email_field.titleize

      expect(page).to have_content guardian_2_information_heading.upcase
      expect(page).to have_content guardian_2_photo_heading.upcase
      expect(page).to have_content guardian_2_email_field.titleize
      expect(page).to have_content guardian_2_phone_field.titleize
      expect(page).to have_content guardian_2_address_street1_field.titleize

      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 guardian_email_field, with: "valid@email.com"
      fill_in person_first_name_field, with: 'Jane'
      fill_in person_last_name_field, with: 'Doe'
      fill_in_person_address_fields
      fill_in person_phone_field, with: '555-555-5555'
      fill_in person_email_field, with: 'jane.doe@test.com'
      drop_file Rails.root.join(file_fixture("person_photo.png")), type: :dropzone
      attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
      draw_signature file_fixture('signature.png'), 'medical_release_signature_base64'

      fill_in_guardian_address_fields
      attach_file guardian_photo_field, file_fixture('hemsworth.jpeg'), visible: :all
      draw_signature file_fixture('signature.png'), 'medical_release_signature_base64'

      fill_in guardian_2_first_name_field, with: 'Second'
      fill_in guardian_2_last_name_field, with: 'Guardian'
      fill_in guardian_2_phone_field, with: '999'

      click_button submit_release_button

      expect(page).to have_content(successful_submission_message)
      expect(MedicalRelease.last.guardian_2_first_name).to eq 'Second'
    end

    scenario 'when signing release, question answers are required', js: true do
      project = create(:project, members: current_user, account: current_user.primary_account)
      contract_template = create(:contract_template,
                                 project: project,
                                 question_1_text: 'Question 1',
                                 question_2_text: 'Question 2'
      )

      visit new_account_project_contract_template_medical_release_path(project.account, project, contract_template)

      fill_in person_first_name_field, with: 'Jane'
      fill_in person_last_name_field, with: 'Doe'
      draw_signature file_fixture("signature.png"), "medical_release_signature_base64"

      expect do
        click_button submit_release_button
      end.to change(MedicalRelease, :count).by(0)
      expect(page).not_to have_content(successful_submission_message)

      fill_in answer_field_for_question(1), with: 'Answer 1'
      draw_signature file_fixture("signature.png"), "medical_release_signature_base64"

      expect do
        click_button submit_release_button
      end.to change(MedicalRelease, :count).by(0)
      expect(page).not_to have_content(successful_submission_message)

      fill_in answer_field_for_question(2), with: 'Answer 2'
      draw_signature file_fixture("signature.png"), "medical_release_signature_base64"

      expect do
        click_button submit_release_button
      end.to change(MedicalRelease, :count).by(1)
      expect(page).to have_content(successful_submission_message)

    end

    scenario "creating a release, if contract template contains signature legal language, it is shown" do
      contract_template = create(:contract_template, project: project, signature_legal_text: dummy_signature_legal_text)
      visit new_account_project_contract_template_medical_release_path(project.account, project, contract_template)

      expect(page).to have_content dummy_signature_legal_text
    end
  end

  context "when signed in as account manager" do
    before do
      sign_in current_user
    end

    scenario "Approved releases have checkmark and non-approved releases don't have checkmarks" do
      create(:medical_release_with_contract_template, :native, project: project)

      visit project_medical_releases_path(project)
      expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 0)

      create(:medical_release_with_contract_template, :native, project: project, approved_by_user_email: "some@email.com", approved_at: DateTime.now)
      visit project_medical_releases_path(project)

      expect(page).to have_css('i.fa.fa-check-circle.fa-2x', count: 1)
    end

    scenario "Download All is visible" do
      create(:medical_release_with_contract_template, :native, project: project)
      create(:medical_release_with_contract_template, :non_native, project: project)

      visit project_medical_releases_path(project)

      expect(page).to have_content download_all_button
    end

    scenario "Download action in Manage menu is visible" do
      create(:medical_release_with_contract_template, :native, project: project)
      create(:medical_release_with_contract_template, :non_native, project: project)

      visit project_medical_releases_path(project)

      expect(page).to have_link("Download", exact: true, count: 2)
    end

    scenario "Review action in Manage menu is visible" do
      create(:medical_release_with_contract_template, :native, project: project)
      create(:medical_release_with_contract_template, :non_native, project: project)

      visit project_medical_releases_path(project)

      expect(page).to have_link(review_action, exact: true)
    end

    scenario "Downloading PDF of native medical release is possible" do
      native_release = create(:medical_release_with_contract_template, :native, project: project)

      visit project_medical_releases_path(project)

      click_link *view_release_pdf_link_for(native_release)
      expect(content_type).to eq('application/pdf')
    end

    scenario "Reviewing release" do
      create(:medical_release_with_contract_template, :native, project: project)

      visit project_medical_releases_path(project)

      click_link review_action

      expect(page).to have_content review_page_heading
      expect(page).to have_content approve_button
    end

    scenario 'When viewing the contract PDF of approved release there is page for office use only' do
      medical_release = create(:medical_release_with_contract_template,
                               :native,
                               project: project,
                               person_first_name: 'Jane',
                               person_last_name: 'Doe',
                               approved_by_user_name: "Big Joe",
                               approved_by_user_email: "some@email.com",
                               approved_at: DateTime.now)

      sign_in(current_user)
      visit project_medical_releases_path(project)
      click_link *view_release_pdf_link_for(medical_release)

      expect(content_type).to eq('application/pdf')
      expect(content_disposition).to include('inline')
      expect(pdf_body).to have_content for_office_use_only.upcase
      expect(pdf_body).to have_content producer_label
      expect(pdf_body).to have_content production_label
      expect(pdf_body).to have_content issued_to_label
      expect(pdf_body).to have_content issued_by_label
      expect(pdf_body).to have_content date_issued
      expect(pdf_body).to have_content 'Big Joe'
    end

    scenario 'When viewing the contract PDF of not approved release there is no page for office use only' do
      medical_release = create(:medical_release_with_contract_template,
                               :native,
                               project: project,
                               person_first_name: 'Jane',
                               person_last_name: 'Doe')

      sign_in(current_user)
      visit project_medical_releases_path(project)
      click_link *view_release_pdf_link_for(medical_release)

      expect(content_type).to eq('application/pdf')
      expect(content_disposition).to include('inline')
      expect(pdf_body).not_to have_content for_office_use_only.upcase
      expect(pdf_body).not_to have_content producer_label
      expect(pdf_body).not_to have_content production_label
      expect(pdf_body).not_to have_content issued_to_label
      expect(pdf_body).not_to have_content issued_by_label
      expect(pdf_body).not_to have_content date_issued
      expect(pdf_body).not_to have_content 'Big Joe'
    end
  end

  context "when the user is manager(project manager)" do
    let(:current_user) { create(:user, :manager) }

    before do
      sign_in current_user
    end

    scenario "Download All is not visible" do
      create(:medical_release_with_contract_template, :native, project: project)
      create(:medical_release_with_contract_template, :non_native, project: project)

      visit project_medical_releases_path(project)

      expect(page).not_to have_content download_all_button
    end

    scenario "Download action in Manage menu is not visible" do
      create(:medical_release_with_contract_template, :native, project: project)
      create(:medical_release_with_contract_template, :non_native, project: project)

      visit project_medical_releases_path(project)

      expect(page).to have_link("Download", exact: true, count: 0)
    end

    scenario "Review action in Manage menu is not visible" do
      create(:medical_release_with_contract_template, :native, project: project)
      create(:medical_release_with_contract_template, :non_native, project: project)

      visit project_medical_releases_path(project)

      expect(page).not_to have_link(review_action, exact: true)
    end

    scenario "Downloading PDF of native medical release is not possible" do
      native_release = create(:medical_release_with_contract_template, :native, project: project)

      visit project_medical_releases_path(project)

      link = medical_release_contracts_path(native_release, format: 'pdf')
      expect { visit link }.to raise_exception Pundit::NotAuthorizedError
    end

    scenario "Downloading PDF of non native medical release is not possible" do
      non_native_release = create(:medical_release_with_contract_template, :non_native, project: project)

      visit project_medical_releases_path(project)

      link = medical_release_contracts_path(non_native_release, format: 'pdf')
      expect { visit link }.to raise_exception Pundit::NotAuthorizedError
    end
  end

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

    before do
      sign_in current_user
    end

    scenario "Download All is not visible" do
      create(:medical_release_with_contract_template, :native, project: project)
      create(:medical_release_with_contract_template, :non_native, project: project)

      visit project_medical_releases_path(project)

      expect(page).not_to have_content download_all_button
    end

    scenario "Download action in Manage menu is not visible" do
      create(:medical_release_with_contract_template, :native, project: project)
      create(:medical_release_with_contract_template, :non_native, project: project)

      visit project_medical_releases_path(project)

      expect(page).to have_link("Download", exact: true, count: 0)
    end

    scenario "Review action in Manage menu is not visible" do
      create(:medical_release_with_contract_template, :native, project: project)
      create(:medical_release_with_contract_template, :non_native, project: project)

      visit project_medical_releases_path(project)

      expect(page).not_to have_link(review_action, exact: true)
    end

    scenario "Downloading PDF of native medical release is not possible" do
      native_release = create(:medical_release_with_contract_template, :native, project: project)

      visit project_medical_releases_path(project)

      link = medical_release_contracts_path(native_release, format: 'pdf')
      expect { visit link }.to raise_exception Pundit::NotAuthorizedError
    end

    scenario "Downloading PDF of non native medical release is not possible" do
      non_native_release = create(:medical_release_with_contract_template, :non_native, project: project)

      visit project_medical_releases_path(project)

      link = medical_release_contracts_path(non_native_release, format: 'pdf')
      expect { visit link }.to raise_exception Pundit::NotAuthorizedError
    end
  end

  private

  def download_all_button
    'Download All'
  end

  def download_action
    'Download'
  end

  def manage_button
    t 'medical_releases.medical_release.actions.manage'
  end

  def view_release_pdf_link_for(release)
    ['Download', href: medical_release_contracts_path(release, format: 'pdf')]
  end

  def person_first_name_field
    "medical_release[person_first_name]"
  end

  def person_last_name_field
    "medical_release[person_last_name]"
  end

  def person_email_field
    "medical_release[person_email]"
  end

  def person_phone_field
    "medical_release[person_phone]"
  end

  def submit_release_button
    t 'shared.submit_release_short'
  end

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

  def fill_in_person_address_fields
    fill_in person_address_street1_field, with: "123 Test Lane"
    fill_in person_address_city_field, with: "New York"
    fill_in person_address_state_field, with: "NY"
    fill_in person_address_zip_field, with: '1000'
  end

  def fill_in_guardian_address_fields
    fill_in guardian_address_street1_field, with: "124 Test Lane"
    fill_in guardian_address_city_field, with: "New York"
    fill_in guardian_address_state_field, with: "NY"
    fill_in guardian_address_zip_field, with: '1000'
  end

  def person_address_street1_field
    t('helpers.label.medical_release.person_address_street1')
  end

  def person_address_city_field
    t('helpers.label.medical_release.person_address_city')
  end

  def person_address_state_field
    t('helpers.label.medical_release.person_address_state')
  end

  def person_address_zip_field
    t('helpers.label.medical_release.person_address_zip')
  end


  def guardian_first_name_field
    t('helpers.label.medical_release.guardian_first_name')
  end

  def guardian_last_name_field
    t('helpers.label.medical_release.guardian_last_name')
  end

  def guardian_phone_field
    t('helpers.label.medical_release.guardian_phone')
  end

  def guardian_email_field
    t('helpers.label.medical_release.guardian_email')
  end

  def guardian_address_street1_field
    t('helpers.label.medical_release.guardian_address_street1')
  end

  def guardian_address_city_field
    t('helpers.label.medical_release.guardian_address_city')
  end

  def guardian_address_state_field
    t('helpers.label.medical_release.guardian_address_state')
  end

  def guardian_address_zip_field
    t('helpers.label.medical_release.guardian_address_zip')
  end

  def guardian_photo_field
    'medical_release[guardian_photo]'
  end

  def person_is_minor_checkbox
    'medical_release_minor'
  end

  def guardian_2_first_name_field
    t('helpers.label.medical_release.guardian_2_first_name')
  end

  def guardian_2_last_name_field
    t('helpers.label.medical_release.guardian_2_last_name')
  end

  def guardian_2_phone_field
    t('helpers.label.medical_release.guardian_2_phone')
  end

  def guardian_2_email_field
    t('helpers.label.medical_release.guardian_2_email')
  end

  def guardian_2_address_street1_field
    t('helpers.label.medical_release.guardian_2_address_street1')
  end

  def email_validation_error_for(prefix)
    "#{prefix} email is not an email"
  end

  def guardian_photo_heading
    t 'public.medical_releases.new.guardian_photo.heading'
  end

  def guardian_information_heading
    t 'public.medical_releases.new.guardian_info.heading'
  end

  def guardian_2_photo_heading
    t 'public.medical_releases.new.guardian_2_photo.heading'
  end

  def guardian_2_information_heading
    t 'public.medical_releases.new.guardian_2_info.heading'
  end

  def answer_field_for_question(number)
    "medical_release[question_#{number}_answer]"
  end

  def dummy_signature_legal_text
    'Some signature legal language'
  end

  def review_action
    t 'medical_releases.medical_release.actions.review'
  end

  def review_page_heading
    t 'approvals.new.heading', release_type: "Medical Release"
  end

  def approve_button
    t 'approvals.new.actions.approve'
  end

  def for_office_use_only
    t 'contracts.for_office_use_only.heading'
  end

  def producer_label
    t 'contracts.for_office_use_only.description_labels.producer'
  end

  def production_label
    t 'contracts.for_office_use_only.description_labels.production'
  end

  def issued_to_label
    t 'contracts.for_office_use_only.description_labels.issued_to'
  end

  def issued_by_label
    t 'contracts.for_office_use_only.description_labels.issued_by'
  end

  def date_issued
    t 'contracts.for_office_use_only.description_labels.date_issued'
  end
end
