# frozen_string_literal: true

module Idv
  class SsnController < ApplicationController
    include Idv::AvailabilityConcern
    include IdvStepConcern
    include StepIndicatorConcern
    include Steps::ThreatMetrixStepHelper
    include ThreatMetrixConcern

    before_action :confirm_not_rate_limited_after_doc_auth
    before_action :confirm_step_allowed
    before_action :override_csp_for_threat_metrix,
                  if: -> { FeatureManagement.proofing_device_profiling_collecting_enabled? }

    attr_reader :ssn_presenter

    # Keep this code in sync with Idv::InPerson::SsnController

    def show
      @ssn_presenter = Idv::SsnPresenter.new(
        sp_name: decorated_sp_session.sp_name,
        ssn_form: Idv::SsnFormatForm.new(idv_session.ssn),
        step_indicator_steps: step_indicator_steps,
      )

      if ssn_presenter.updating_ssn?
        analytics.idv_doc_auth_redo_ssn_submitted(**analytics_arguments)
      end
      analytics.idv_doc_auth_ssn_visited(**analytics_arguments)

      Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer])
        .call('ssn', :view, true)

      render 'idv/shared/ssn', locals: threatmetrix_view_variables(ssn_presenter.updating_ssn?)
    end

    def update
      clear_future_steps!
      ssn_form = Idv::SsnFormatForm.new(idv_session.ssn)
      form_response = ssn_form.submit(ssn: ssn_params[:ssn])

      @ssn_presenter = Idv::SsnPresenter.new(
        sp_name: decorated_sp_session.sp_name,
        ssn_form: ssn_form,
        step_indicator_steps: step_indicator_steps,
      )

      attempts_api_tracker.idv_ssn_submitted(
        success: form_response.success?,
        ssn: ssn_params[:ssn],
        failure_reason: attempts_api_tracker.parse_failure_reason(form_response),
      )

      fraud_ops_tracker.idv_ssn_submitted(
        success: form_response.success?,
        ssn: ssn_params[:ssn],
        failure_reason: fraud_ops_tracker.parse_failure_reason(form_response),
      )

      if form_response.success?
        idv_session.previous_ssn = idv_session.ssn
        idv_session.ssn = SsnFormatter.normalize(ssn_params[:ssn])
        redirect_to next_url
      else
        flash[:error] = form_response.first_error_message
        render 'idv/shared/ssn', locals: threatmetrix_view_variables(ssn_presenter.updating_ssn?)
      end

      analytics.idv_doc_auth_ssn_submitted(
        **analytics_arguments.merge(form_response.to_h),
      )
    end

    def self.step_info
      Idv::StepInfo.new(
        key: :ssn,
        controller: self,
        next_steps: [:verify_info],
        preconditions: ->(idv_session:, user:) { idv_session.remote_document_capture_complete? },
        undo_step: ->(idv_session:, user:) {
          idv_session.invalidate_ssn_step!
        },
      )
    end

    private

    def next_url
      if idv_session.pii_from_doc.residential_address_required? && !ssn_presenter.updating_ssn?
        idv_address_url
      else
        idv_verify_info_url
      end
    end

    def analytics_arguments
      {
        flow_path: idv_session.flow_path,
        step: 'ssn',
        analytics_id: 'Doc Auth',
        previous_ssn_edit_distance: previous_ssn_edit_distance,
      }.merge(ab_test_analytics_buckets)
    end

    def ssn_params
      params.require(:doc_auth).permit(:ssn)
    end
  end
end
