# frozen_string_literal: true

RSpec.describe 'Signing Form' do
  let(:account) { create(:account) }
  let(:author) { create(:user, account:) }

  context 'when the template form link is opened' do
    let(:template) do
      create(:template, shared_link: true, account:, author:, except_field_types: %w[phone payment stamp])
    end

    it 'displays only the email step when only email is required' do
      visit start_form_path(slug: template.slug)

      expect(page).to have_content('You have been invited to submit a form')
      expect(page).to have_content("Invited by #{account.name}")
      expect(page).to have_field('Email', type: 'email', placeholder: 'Provide your email to start')
      expect(page).not_to have_field('Phone', type: 'tel')
      expect(page).not_to have_field('Name', type: 'text')
      expect(page).to have_button('Start')
    end

    it 'displays name, email, and phone fields together when all are required' do
      template.update(preferences: { link_form_fields: %w[email name phone] })

      visit start_form_path(slug: template.slug)

      expect(page).to have_content('You have been invited to submit a form')
      expect(page).to have_content("Invited by #{account.name}")
      expect(page).to have_field('Email', type: 'email', placeholder: 'Provide your email')
      expect(page).to have_field('Name', type: 'text', placeholder: 'Provide your name')
      expect(page).to have_field('Phone', type: 'tel', placeholder: 'Provide your phone in international format')
      expect(page).to have_button('Start')
    end

    it 'displays only the name step when only name is required' do
      template.update(preferences: { link_form_fields: %w[name] })

      visit start_form_path(slug: template.slug)

      expect(page).to have_content('You have been invited to submit a form')
      expect(page).to have_content("Invited by #{account.name}")
      expect(page).to have_field('Name', type: 'text', placeholder: 'Provide your name to start')
      expect(page).not_to have_field('Phone', type: 'tel')
      expect(page).not_to have_field('Email', type: 'email')
      expect(page).to have_button('Start')
    end

    it 'displays only the phone step when only phone is required' do
      template.update(preferences: { link_form_fields: %w[phone] })

      visit start_form_path(slug: template.slug)

      expect(page).to have_content('You have been invited to submit a form')
      expect(page).to have_content("Invited by #{account.name}")
      expect(page).to have_field('Phone', type: 'tel',
                                          placeholder: 'Provide your phone in international format to start')
      expect(page).not_to have_field('Name', type: 'text')
      expect(page).not_to have_field('Email', type: 'email')
      expect(page).to have_button('Start')
    end

    it 'prevents starting the form if phone is not in international format' do
      template.update(preferences: { link_form_fields: %w[phone] })

      visit start_form_path(slug: template.slug)

      fill_in 'Phone', with: '12345'

      expect { click_button 'Start' }.not_to(change { current_path })
    end

    it 'prevents starting the form if email is invali' do
      visit start_form_path(slug: template.slug)

      fill_in 'Email', with: 'invalid-email'

      expect { click_button 'Start' }.not_to(change { current_path })
    end

    it 'completes the form' do
      visit start_form_path(slug: template.slug)

      # Submit's email step
      fill_in 'Email', with: 'john.dou@example.com'
      click_button 'Start'

      # Text step
      fill_in 'First Name', with: 'John'
      click_button 'next'

      # Date step
      fill_in 'Birthday', with: I18n.l(20.years.ago, format: '%Y-%m-%d')
      click_button 'next'

      # Checkbox step
      check 'Do you agree?'
      click_button 'next'

      # Radio step
      choose 'Boy'
      click_button 'next'

      # Signature step
      draw_canvas
      click_button 'next'

      # Number step
      fill_in 'House number', with: '123'
      click_button 'next'

      # Multiple choice step
      %w[Red Blue].each { |color| check color }
      click_button 'next'

      # Select step
      select 'Male', from: 'Gender'
      click_button 'next'

      # Initials step
      draw_canvas
      click_button 'next'

      # Image step
      find('#dropzone').click
      find('input[type="file"]', visible: false).attach_file(Rails.root.join('spec/fixtures/sample-image.png'))
      click_button 'next'

      # File step
      find('#dropzone').click
      find('input[type="file"]', visible: false).attach_file(Rails.root.join('spec/fixtures/sample-document.pdf'))
      click_button 'next'

      # Cell step
      fill_in 'Cell code', with: '123'
      find('#submit_form_button').click

      expect(page).to have_button('Download')
      expect(page).to have_content('Document has been signed!')

      submitter = template.submissions.last.submitters.last

      expect(submitter.email).to eq('john.dou@example.com')
      expect(submitter.ip).to eq('127.0.0.1')
      expect(submitter.ua).to be_present
      expect(submitter.opened_at).to be_present
      expect(submitter.completed_at).to be_present
      expect(submitter.declined_at).to be_nil

      expect(field_value(submitter, 'First Name')).to eq 'John'
      expect(field_value(submitter, 'Birthday')).to eq 20.years.ago.strftime('%Y-%m-%d')
      expect(field_value(submitter, 'Do you agree?')).to be_truthy
      expect(field_value(submitter, 'First child')).to eq 'Boy'
      expect(field_value(submitter, 'Signature')).to be_present
      expect(field_value(submitter, 'House number')).to eq 123
      expect(field_value(submitter, 'Colors')).to contain_exactly('Red', 'Blue')
      expect(field_value(submitter, 'Gender')).to eq 'Male'
      expect(field_value(submitter, 'Initials')).to be_present
      expect(field_value(submitter, 'Avatar')).to be_present
      expect(field_value(submitter, 'Attachment')).to be_present
      expect(field_value(submitter, 'Cell code')).to eq '123'
    end

    it 'completes the form when name, email, and phone are required' do
      template.update(preferences: { link_form_fields: %w[email name phone] })

      visit start_form_path(slug: template.slug)

      # Submit's name, email, and phone step
      fill_in 'Email', with: 'john.dou@example.com'
      fill_in 'Name', with: 'John Doe'
      fill_in 'Phone', with: '+17732298825'
      click_button 'Start'

      # Text step
      fill_in 'First Name', with: 'John'
      click_button 'next'

      # Date step
      fill_in 'Birthday', with: I18n.l(20.years.ago, format: '%Y-%m-%d')
      click_button 'next'

      # Checkbox step
      check 'Do you agree?'
      click_button 'next'

      # Radio step
      choose 'Boy'
      click_button 'next'

      # Signature step
      draw_canvas
      click_button 'next'

      # Number step
      fill_in 'House number', with: '123'
      click_button 'next'

      # Multiple choice step
      %w[Red Blue].each { |color| check color }
      click_button 'next'

      # Select step
      select 'Male', from: 'Gender'
      click_button 'next'

      # Initials step
      draw_canvas
      click_button 'next'

      # Image step
      find('#dropzone').click
      find('input[type="file"]', visible: false).attach_file(Rails.root.join('spec/fixtures/sample-image.png'))
      click_button 'next'

      # File step
      find('#dropzone').click
      find('input[type="file"]', visible: false).attach_file(Rails.root.join('spec/fixtures/sample-document.pdf'))
      click_button 'next'

      # Cell step
      fill_in 'Cell code', with: '123'
      find('#submit_form_button').click

      expect(page).to have_button('Download')
      expect(page).to have_content('Document has been signed!')

      submitter = template.submissions.last.submitters.last

      expect(submitter.email).to eq('john.dou@example.com')
      expect(submitter.name).to eq('John Doe')
      expect(submitter.phone).to eq('+17732298825')
      expect(submitter.ip).to eq('127.0.0.1')
      expect(submitter.ua).to be_present
      expect(submitter.opened_at).to be_present
      expect(submitter.completed_at).to be_present
      expect(submitter.declined_at).to be_nil

      expect(field_value(submitter, 'First Name')).to eq 'John'
      expect(field_value(submitter, 'Birthday')).to eq 20.years.ago.strftime('%Y-%m-%d')
      expect(field_value(submitter, 'Do you agree?')).to be_truthy
      expect(field_value(submitter, 'First child')).to eq 'Boy'
      expect(field_value(submitter, 'Signature')).to be_present
      expect(field_value(submitter, 'House number')).to eq 123
      expect(field_value(submitter, 'Colors')).to contain_exactly('Red', 'Blue')
      expect(field_value(submitter, 'Gender')).to eq 'Male'
      expect(field_value(submitter, 'Initials')).to be_present
      expect(field_value(submitter, 'Avatar')).to be_present
      expect(field_value(submitter, 'Attachment')).to be_present
      expect(field_value(submitter, 'Cell code')).to eq '123'
    end

    it 'completes the form when identity verification with a 2FA code is enabled', sidekiq: :inline do
      create(:encrypted_config, key: EncryptedConfig::ESIGN_CERTS_KEY,
                                value: GenerateCertificate.call.transform_values(&:to_pem))

      template.update(preferences: { link_form_fields: %w[email name], shared_link_2fa: true })

      visit start_form_path(slug: template.slug)

      fill_in 'Email', with: 'john.dou@example.com'
      fill_in 'Name', with: 'John Doe'

      expect do
        click_button 'Start'
      end.to change { ActionMailer::Base.deliveries.count }.by(1)

      email = ActionMailer::Base.deliveries.last
      code = email.body.encoded[%r{<b>(.*?)</b>}, 1]

      fill_in 'one_time_code', with: code

      click_button 'Submit'

      fill_in 'First Name', with: 'John'
      click_button 'next'

      fill_in 'Birthday', with: I18n.l(20.years.ago, format: '%Y-%m-%d')
      click_button 'next'

      check 'Do you agree?'
      click_button 'next'

      choose 'Boy'
      click_button 'next'

      draw_canvas
      click_button 'next'

      fill_in 'House number', with: '123'
      click_button 'next'

      %w[Red Blue].each { |color| check color }
      click_button 'next'

      select 'Male', from: 'Gender'
      click_button 'next'

      draw_canvas
      click_button 'next'

      find('#dropzone').click
      find('input[type="file"]', visible: false).attach_file(Rails.root.join('spec/fixtures/sample-image.png'))
      click_button 'next'

      find('#dropzone').click
      find('input[type="file"]', visible: false).attach_file(Rails.root.join('spec/fixtures/sample-document.pdf'))
      click_button 'next'

      fill_in 'Cell code', with: '123'
      find('#submit_form_button').click

      expect(page).to have_button('Download')
      expect(page).to have_content('Document has been signed!')

      submitter = template.submissions.last.submitters.last

      expect(submitter.email).to eq('john.dou@example.com')
      expect(submitter.name).to eq('John Doe')
      expect(submitter.ip).to eq('127.0.0.1')
      expect(submitter.ua).to be_present
      expect(submitter.opened_at).to be_present
      expect(submitter.completed_at).to be_present
      expect(submitter.declined_at).to be_nil

      expect(field_value(submitter, 'First Name')).to eq 'John'
      expect(field_value(submitter, 'Birthday')).to eq 20.years.ago.strftime('%Y-%m-%d')
      expect(field_value(submitter, 'Do you agree?')).to be_truthy
      expect(field_value(submitter, 'First child')).to eq 'Boy'
      expect(field_value(submitter, 'Signature')).to be_present
      expect(field_value(submitter, 'House number')).to eq 123
      expect(field_value(submitter, 'Colors')).to contain_exactly('Red', 'Blue')
      expect(field_value(submitter, 'Gender')).to eq 'Male'
      expect(field_value(submitter, 'Initials')).to be_present
      expect(field_value(submitter, 'Avatar')).to be_present
      expect(field_value(submitter, 'Attachment')).to be_present
      expect(field_value(submitter, 'Cell code')).to eq '123'
    end
  end

  context 'when the submitter form link is opened' do
    let(:template) { create(:template, account:, author:, except_field_types: %w[phone payment stamp]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:, email: 'robin@example.com')
    end

    before do
      visit submit_form_path(slug: submitter.slug)
    end

    it 'complete the form' do
      # Text step
      fill_in 'First Name', with: 'John'
      click_button 'next'

      # Date step
      fill_in 'Birthday', with: I18n.l(20.years.ago, format: '%Y-%m-%d')
      click_button 'next'

      # Checkbox step
      check 'Do you agree?'
      click_button 'next'

      # Radio step
      choose 'Boy'
      click_button 'next'

      # Signature step
      draw_canvas
      click_button 'next'

      # Number step
      fill_in 'House number', with: '123'
      click_button 'next'

      # Multiple choice step
      %w[Red Blue].each { |color| check color }
      click_button 'next'

      # Select step
      select 'Male', from: 'Gender'
      click_button 'next'

      # Initials step
      draw_canvas
      click_button 'next'

      # Image step
      find('#dropzone').click
      find('input[type="file"]', visible: false).attach_file(Rails.root.join('spec/fixtures/sample-image.png'))
      click_button 'next'

      # File step
      find('#dropzone').click
      find('input[type="file"]', visible: false).attach_file(Rails.root.join('spec/fixtures/sample-document.pdf'))
      click_button 'next'

      # Cell step
      fill_in 'Cell code', with: '123'
      find('#submit_form_button').click

      expect(page).to have_button('Download')
      expect(page).to have_content('Document has been signed!')

      submitter.reload

      expect(submitter.email).to eq 'robin@example.com'
      expect(submitter.ip).to eq('127.0.0.1')
      expect(submitter.ua).to be_present
      expect(submitter.opened_at).to be_present
      expect(submitter.completed_at).to be_present
      expect(submitter.declined_at).to be_nil

      expect(field_value(submitter, 'First Name')).to eq 'John'
      expect(field_value(submitter, 'Birthday')).to eq 20.years.ago.strftime('%Y-%m-%d')
      expect(field_value(submitter, 'Do you agree?')).to be_truthy
      expect(field_value(submitter, 'First child')).to eq 'Boy'
      expect(field_value(submitter, 'Signature')).to be_present
      expect(field_value(submitter, 'House number')).to eq 123
      expect(field_value(submitter, 'Colors')).to contain_exactly('Red', 'Blue')
      expect(field_value(submitter, 'Gender')).to eq 'Male'
      expect(field_value(submitter, 'Initials')).to be_present
      expect(field_value(submitter, 'Avatar')).to be_present
      expect(field_value(submitter, 'Attachment')).to be_present
      expect(field_value(submitter, 'Cell code')).to eq '123'
    end
  end

  context 'when the text step' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[text]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:)
    end

    it 'completes the form if the field is filled' do
      visit submit_form_path(slug: submitter.slug)

      input = find_field('First Name')

      expect(input[:required]).to be_truthy
      expect(input[:placeholder]).to eq 'Type here...'

      fill_in 'First Name', with: 'Mary'
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'First Name')).to eq 'Mary'
    end

    it 'toggle multiple text button' do
      visit submit_form_path(slug: submitter.slug)

      input = find_field('First Name')

      expect(input.tag_name).to eq('input')

      find(:css, 'div[data-tip="Toggle Multiline Text"]').click

      input = find_field('First Name')

      expect(input.tag_name).to eq('textarea')
      expect(page).not_to have_selector(:css, 'div[data-tip="Toggle Multiline Text"]')

      fill_in 'First Name', with: 'Very long text'
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(field_value(submitter, 'First Name')).to eq 'Very long text'
      expect(submitter.completed_at).to be_present
    end
  end

  context 'when the date step' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[date]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:)
    end

    it 'completes the form if the field is filled' do
      visit submit_form_path(slug: submitter.slug)

      input = find_field('Birthday')

      expect(input[:required]).to be_truthy

      fill_in 'Birthday', with: I18n.l(25.years.ago, format: '%Y-%m-%d')
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Birthday')).to eq 25.years.ago.strftime('%Y-%m-%d')
    end

    it 'pre-fills the current date into the form field' do
      visit submit_form_path(slug: submitter.slug)

      input = find_field('Birthday')

      expect(input[:value]).to eq ''

      click_button 'Set Today'

      input = find_field('Birthday')

      expect(input[:value]).to eq Time.zone.now.strftime('%Y-%m-%d')

      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Birthday')).to eq Time.zone.now.strftime('%Y-%m-%d')
    end
  end

  context 'when the checkbox step' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[checkbox]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:)
    end

    it 'completes the form if the checkbox is checked' do
      visit submit_form_path(slug: submitter.slug)

      check 'Do you agree?'
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Do you agree?')).to be true
    end
  end

  context 'when the radio step' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[radio]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:)
    end

    it 'completes the form if the checkbox is checked' do
      visit submit_form_path(slug: submitter.slug)

      %w[Girl Boy].map { |v| find_field(v) }.each { |input| expect(input[:required]).to be_truthy }

      choose 'Boy'
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'First child')).to eq 'Boy'
    end
  end

  context 'when the signature step' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[signature]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:)
    end

    it 'completes the form if the canvas is drawn' do
      visit submit_form_path(slug: submitter.slug)

      find('#expand_form_button').click
      draw_canvas
      click_button 'Sign and Complete'

      expect(page).to have_content('Document has been signed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Signature')).to be_present
    end

    it 'shows an error message if the canvas is not drawn or too simple' do
      visit submit_form_path(slug: submitter.slug)

      find('#expand_form_button').click
      page.find('canvas').click([], { x: 150, y: 100 })

      alert_text = page.accept_alert do
        click_button 'Sign and Complete'
      end

      expect(alert_text).to eq 'Signature is too small or simple. Please redraw.'
    end

    it 'completes the form if the canvas is typed' do
      visit submit_form_path(slug: submitter.slug)

      find('#expand_form_button').click
      click_button 'Type'
      fill_in 'signature_text_input', with: 'John Doe'
      click_button 'Sign and Complete'

      expect(page).to have_content('Document has been signed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Signature')).to be_present
    end
  end

  context 'when the signature step with signing reason' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[signature]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:)
    end

    before do
      create(:account_config, account:, key: AccountConfig::REQUIRE_SIGNING_REASON_KEY, value: true)
    end

    it 'completes the form with signing reason selected' do
      visit submit_form_path(slug: submitter.slug)

      find('#expand_form_button').click
      draw_canvas
      select 'Approved'
      click_button 'Sign and Complete'

      expect(page).to have_content('Document has been signed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Signature')).to be_present
    end
  end

  context 'when the number step' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[number]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:)
    end

    it 'completes the form if the field is filled' do
      visit submit_form_path(slug: submitter.slug)

      input = find_field('House number')

      expect(input[:required]).to be_truthy
      expect(input[:placeholder]).to eq 'Type here...'

      fill_in 'House number', with: '4'
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'House number')).to eq 4
    end
  end

  context 'when the multiple choice step' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[multiple]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:)
    end

    it 'completes the form if the multiple choice is checked' do
      visit submit_form_path(slug: submitter.slug)

      %w[Red Green].each { |color| check color }
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Colors')).to contain_exactly('Red', 'Green')
    end
  end

  context 'when the select step' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[select]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:)
    end

    it 'completes the form if the multiple choice is checked' do
      visit submit_form_path(slug: submitter.slug)

      select 'Female', from: 'Gender'

      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Gender')).to eq 'Female'
    end
  end

  context 'when the initials step' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[initials]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:)
    end

    it 'completes the form if the canvas is typed' do
      visit submit_form_path(slug: submitter.slug)

      find('#expand_form_button').click
      fill_in 'initials_text_input', with: 'John Doe'
      find('#submit_form_button').click

      expect(page).to have_content('Document has been signed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Initials')).to be_present
    end

    it 'completes the form if the canvas is drawn' do
      visit submit_form_path(slug: submitter.slug)

      find('#expand_form_button').click
      click_button 'Draw'
      draw_canvas
      find('#submit_form_button').click

      expect(page).to have_content('Document has been signed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Initials')).to be_present
    end

    it 'completes the form if the initials is uploaded' do
      visit submit_form_path(slug: submitter.slug)

      find('#expand_form_button').click
      find('span[data-tip="Click to upload"]').click
      find('input[type="file"]', visible: false).attach_file(Rails.root.join('spec/fixtures/sample-image.png'))

      sleep 0.1

      find('#submit_form_button').click

      expect(page).to have_content('Document has been signed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Initials')).to be_present
    end
  end

  context 'when the image step' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[image]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:)
    end

    it 'completes the form if the image is uploaded' do
      visit submit_form_path(slug: submitter.slug)

      find('#expand_form_button').click
      find('#dropzone').click
      find('input[type="file"]', visible: false).attach_file(Rails.root.join('spec/fixtures/sample-image.png'))
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Avatar')).to be_present
    end
  end

  context 'when the file step' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[file]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:)
    end

    it 'completes the form if the file is uploaded' do
      visit submit_form_path(slug: submitter.slug)

      find('#expand_form_button').click
      find('#dropzone').click
      find('input[type="file"]', visible: false).attach_file(Rails.root.join('spec/fixtures/sample-document.pdf'))
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Attachment')).to be_present
    end
  end

  context 'when the cells step' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[cells]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:)
    end

    it 'completes the form if the field is filled' do
      visit submit_form_path(slug: submitter.slug)

      input = find_field('Cell code')

      expect(input[:required]).to be_truthy
      expect(input[:placeholder]).to eq 'Type here...'

      fill_in 'Cell code', with: '456'
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Cell code')).to eq '456'
    end
  end

  context 'when the field with conditions' do
    let(:template) { create(:template, account:, author:, only_field_types: ['text']) }
    let(:submission) { create(:submission, :with_submitters, template:) }
    let(:template_attachment) { template.schema.first }
    let(:template_submitter) { submission.template_submitters.first }
    let(:submitter) { submission.submitters.first }
    let(:fields) do
      [
        {
          'uuid' => 'da7e0d56-fdb0-441a-bbed-d0f6f2e10fd6',
          'submitter_uuid' => submitter.uuid,
          'name' => 'Full Name',
          'type' => 'text',
          'required' => false,
          'preferences' => {},
          'conditions' => [],
          'areas' => [
            {
              'x' => 0.1117351575121163,
              'y' => 0.08950650415231329,
              'w' => 0.2,
              'h' => 0.02857142857142857,
              'attachment_uuid' => template_attachment['attachment_uuid'],
              'page' => 0
            }
          ]
        },
        {
          'uuid' => 'd32ad52a-8f6b-4e32-b0d6-6258fb47440b',
          'submitter_uuid' => submitter.uuid,
          'name' => 'Email',
          'type' => 'text',
          'required' => false,
          'preferences' => {},
          'conditions' => [],
          'validation' => { 'pattern' => '^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$' },
          'areas' => [
            {
              'x' => 0.1097914983844911,
              'y' => 0.1417641720258019,
              'w' => 0.2,
              'h' => 0.02857142857142857,
              'attachment_uuid' => template_attachment['attachment_uuid'],
              'page' => 0
            }
          ]
        },
        {
          'uuid' => 'c6e013ae-f9f6-4b3a-ad33-b7e772a0a49f',
          'submitter_uuid' => submitter.uuid,
          'name' => 'Phone',
          'type' => 'text',
          'required' => false,
          'preferences' => {},
          'areas' => [
            {
              'x' => 0.1100060581583199,
              'y' => 0.2553160344676159,
              'w' => 0.2,
              'h' => 0.02857142857142857,
              'attachment_uuid' => template_attachment['attachment_uuid'],
              'page' => 0
            }
          ]
        },
        {
          'uuid' => '64523936-22fd-41f8-b997-ede8fbe467cc',
          'submitter_uuid' => submitter.uuid,
          'name' => 'Comment',
          'type' => 'text',
          'required' => false,
          'preferences' => {},
          'conditions' => [
            { 'field_uuid' => 'da7e0d56-fdb0-441a-bbed-d0f6f2e10fd6', 'action' => 'not_empty' },
            { 'field_uuid' => 'd32ad52a-8f6b-4e32-b0d6-6258fb47440b', 'action' => 'not_empty' },
            { 'field_uuid' => 'c6e013ae-f9f6-4b3a-ad33-b7e772a0a49f', 'action' => 'not_empty', 'operation' => 'or' }
          ],
          'areas' => [
            {
              'x' => 0.1145875403877221,
              'y' => 0.1982961365432846,
              'w' => 0.2,
              'h' => 0.02857142857142857,
              'attachment_uuid' => template_attachment['attachment_uuid'],
              'page' => 0
            }
          ]
        }
      ]
    end

    before do
      template.update(fields:)
      submission.update(template_fields: fields)
    end

    it 'completes the form and saves the conditional field when all required fields are filled' do
      visit submit_form_path(slug: submitter.slug)
      fill_in 'Full Name (optional)', with: 'John Doe'
      click_button 'next'

      fill_in 'Email (optional)', with: 'john.due@example.com'
      click_button 'next'

      fill_in 'Phone (optional)', with: '+1 (773) 229-8825'
      click_button 'next'

      fill_in 'Comment', with: 'This is a comment'
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Full Name')).to eq 'John Doe'
      expect(field_value(submitter, 'Email')).to eq 'john.due@example.com'
      expect(field_value(submitter, 'Phone')).to eq '+1 (773) 229-8825'
      expect(field_value(submitter, 'Comment')).to eq 'This is a comment'
    end

    it 'completes the form and saves the conditional field when minimum required fields are filled' do
      visit submit_form_path(slug: submitter.slug)
      fill_in 'Full Name (optional)', with: 'John Doe'
      click_button 'next'

      fill_in 'Email (optional)', with: 'john.due@example.com'
      click_button 'next'

      fill_in 'Phone (optional)', with: ''
      click_button 'next'

      fill_in 'Comment', with: 'This is a comment'
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Full Name')).to eq 'John Doe'
      expect(field_value(submitter, 'Email')).to eq 'john.due@example.com'
      expect(field_value(submitter, 'Phone')).to be_empty
      expect(field_value(submitter, 'Comment')).to eq 'This is a comment'
    end

    it 'completes the form without saving the conditional field when not enough fields are filled' do
      visit submit_form_path(slug: submitter.slug)

      fill_in 'Full Name (optional)', with: 'Jane Doe'
      click_button 'next'

      fill_in 'Email (optional)', with: ''
      click_button 'next'

      fill_in 'Phone (optional)', with: ''
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Full Name')).to eq 'Jane Doe'
      expect(field_value(submitter, 'Email')).to be_empty
      expect(field_value(submitter, 'Phone')).to be_empty
      expect(field_value(submitter, 'Comment')).to be_nil
    end

    it 'completes the form without saving the conditional field when only partial fields are filled' do
      visit submit_form_path(slug: submitter.slug)

      fill_in 'Full Name (optional)', with: ''
      click_button 'next'

      fill_in 'Email (optional)', with: 'john.due@example.com'
      click_button 'next'

      fill_in 'Phone (optional)', with: '+1 (773) 229-8825'
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'Full Name')).to be_empty
      expect(field_value(submitter, 'Email')).to eq 'john.due@example.com'
      expect(field_value(submitter, 'Phone')).to eq '+1 (773) 229-8825'
      expect(field_value(submitter, 'Comment')).to be_nil
    end
  end

  context 'when the masked field' do
    let(:template) { create(:template, submitter_count: 2, account:, author:, only_field_types: %w[text]) }
    let(:submission) { create(:submission, template: template) }
    let!(:first_submitter) { create(:submitter, submission:, uuid: template.submitters[0]['uuid'], account:) }
    let!(:second_submitter) { create(:submitter, submission:, uuid: template.submitters[1]['uuid'], account:) }

    it 'shows the masked value instead of the real value' do
      field = submission.template_fields.find do |f|
        f['name'] == 'First Name' && f['submitter_uuid'] == first_submitter.uuid
      end
      field['preferences']['mask'] = true
      submission.save!

      visit submit_form_path(slug: first_submitter.slug)

      fill_in 'First Name', with: 'Jahn'
      find('#submit_form_button').click

      visit submit_form_path(slug: second_submitter.slug)

      expect(page).to have_content('XXXX')
    end
  end

  context 'when the template requires multiple submitters' do
    let(:template) do
      create(:template, shared_link: true, submitter_count: 2, account:, author:, only_field_types: %w[text])
    end

    context 'when default signer details are not defined' do
      it 'shows an explanation error message if a logged-in user associated with the template account opens the link' do
        sign_in author
        visit start_form_path(slug: template.slug)
        fill_in 'Email', with: author.email
        click_button 'Start'

        expect(page).to have_content('This submission has multiple signers, which prevents the use of a sharing link ' \
                                     "as it's unclear which signer is responsible for specific fields. " \
                                     'To resolve this, follow this guide to define the default signer details.')
        expect(page).to have_link('guide', href: 'https://www.docuseal.com/resources/pre-filling-recipients')
      end

      it 'shows a "Not found" error message if a logged-out user associated with the template account opens the link' do
        visit start_form_path(slug: template.slug)
        fill_in 'Email', with: author.email
        click_button 'Start'

        expect(page).to have_content('Not found')
      end

      it 'shows a "Not found" error message if an unrelated user opens the link' do
        visit start_form_path(slug: template.slug)
        fill_in 'Email', with: 'john.doe@example.com'
        click_button 'Start'

        expect(page).to have_content('Not found')
      end
    end
  end

  context 'when the template shared link is disabled' do
    let(:template) do
      create(:template, shared_link: false, account:, author:, only_field_types: %w[text])
    end

    context 'when user is logged in' do
      before do
        login_as author
        visit start_form_path(slug: template.slug)
      end

      it 'shows a warning that the shared link is disabled and provides an option to enable it' do
        expect(page).to have_content('Share link is currently disabled')
        expect(page).to have_content(template.name)
        expect(page).to have_button('Enable shared link')
      end

      it 'enables the shared link' do
        expect do
          click_button 'Enable shared link'
        end.to change { template.reload.shared_link }.from(false).to(true)

        expect(page).to have_content('You have been invited to submit a form')
      end
    end
  end

  context 'when a form is completed' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[text signature]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) { create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:) }

    before do
      visit submit_form_path(slug: submitter.slug)
    end

    it 'sends completed email' do
      fill_in 'First Name', with: 'Adam'
      click_on 'next'
      draw_canvas

      expect do
        click_on 'Sign and Complete'
      end.to change(ProcessSubmitterCompletionJob.jobs, :size).by(1)
    end
  end

  context 'when decline is enabled' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[text]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) { create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:) }

    it 'declines the form and shows the declined page' do
      visit submit_form_path(slug: submitter.slug)

      find('#decline_button').click
      fill_in 'reason', with: 'I do not agree with the terms'
      within('dialog[open]') { click_button 'Decline' }

      expect(page).to have_content('Form has been declined')

      submitter.reload

      expect(submitter.declined_at).to be_present
    end
  end

  context 'when delegate is enabled' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[text]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) { create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:) }

    before do
      create(:account_config, account:, key: AccountConfig::ALLOW_TO_DELEGATE_KEY, value: true)
    end

    it 'delegates the form to another email and shows the delegated page' do
      visit submit_form_path(slug: submitter.slug)

      find('#delegate_button').click
      fill_in 'email', with: 'delegate@example.com'
      within('dialog[open]') { click_button 'Delegate' }

      expect(page).to have_content('Document has been delegated')

      submitter.reload

      expect(submitter.email).to eq('delegate@example.com')
    end
  end

  context 'when the 2FA email verification is enabled', sidekiq: :inline do
    let(:template) { create(:template, account:, author:, only_field_types: %w[text]) }
    let(:submission) { create(:submission, template:) }
    let(:submitter) do
      create(:submitter, submission:, uuid: template.submitters.first['uuid'], account:)
    end

    before do
      template.update(preferences: { require_email_2fa: true })
      create(:encrypted_config, key: EncryptedConfig::ESIGN_CERTS_KEY,
                                value: GenerateCertificate.call.transform_values(&:to_pem))
    end

    it 'completes the form if the one-time password is filled correctly' do
      visit submit_form_path(slug: submitter.slug)

      click_button 'Send verification code'

      email = ActionMailer::Base.deliveries.last
      one_time_code = email.body.encoded[%r{<b>(\d{6})</b>}, 1]

      fill_in 'one_time_code', with: one_time_code

      click_button 'Submit'

      fill_in 'First Name', with: 'Mary'
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'First Name')).to eq 'Mary'
    end

    it "doesn't complete the form if the one-time code is invalid" do
      visit submit_form_path(slug: submitter.slug)

      click_button 'Send verification code'
      fill_in 'one_time_code', with: '123456'
      click_button 'Submit'

      expect(page).to have_content 'Invalid code'
    end

    it 'completes the form after resending the one time code' do
      visit submit_form_path(slug: submitter.slug)

      click_button 'Send verification code'

      find('#resend_label').click

      email = ActionMailer::Base.deliveries.last
      one_time_code = email.body.encoded[%r{<b>(\d{6})</b>}, 1]

      fill_in 'one_time_code', with: one_time_code

      click_button 'Submit'

      fill_in 'First Name', with: 'Mary'
      find('#submit_form_button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'First Name')).to eq 'Mary'
    end
  end

  context 'when header complete button' do
    let(:template) { create(:template, account:, author:, only_field_types: %w[text date]) }
    let(:submission) { create(:submission, :with_submitters, template:) }
    let(:submitter) { submission.submitters.first }

    before do
      template.fields.second['required'] = false
      template.save!
      submission.update(template_fields: template.fields)
    end

    it 'shows header complete button and hides download after filling required fields' do
      visit submit_form_path(slug: submitter.slug)

      expect(page).to have_button('Decline')
      expect(page).to have_css('download-button[aria-label="Download"]', visible: true)
      expect(page).not_to have_css('#complete_button_container button')

      fill_in 'First Name', with: 'John Doe'
      click_button 'next'

      expect(page).to have_css('#complete_button_container button')
      expect(page).to have_button('Decline')
      expect(page).to have_css('download-button[aria-label="Download"]', visible: :hidden)
    end

    it 'completes the form via header complete button skipping optional fields' do
      visit submit_form_path(slug: submitter.slug)

      fill_in 'First Name', with: 'John Doe'
      click_button 'next'

      find('#complete_button_container button').click

      expect(page).to have_content('Form has been completed!')

      submitter.reload

      expect(submitter.completed_at).to be_present
      expect(field_value(submitter, 'First Name')).to eq 'John Doe'
    end
  end
end
