# frozen_string_literal: true

# Sentry configuration for error tracking and performance monitoring
# Only initializes if SENTRY_DSN is configured

return unless ENV['SENTRY_DSN'].present?

require 'sentry-rails'

Sentry.init do |config|
  config.dsn = ENV['SENTRY_DSN']

  # Configure sampling for production (lower in production, higher in staging)
  config.traces_sample_rate = case Rails.env
                              when 'production' then ENV.fetch('SENTRY_TRACES_SAMPLE_RATE', '0.05').to_f
                              when 'staging' then ENV.fetch('SENTRY_TRACES_SAMPLE_RATE', '0.2').to_f
                              else ENV.fetch('SENTRY_TRACES_SAMPLE_RATE', '0.1').to_f
                              end

  # Enable breadcrumbs for better debugging
  config.breadcrumbs_logger = [:active_support_logger, :http_logger]

  # Send PII data (like IPs) to Sentry for debugging (disable in production if needed)
  config.send_default_pii = ENV.fetch('SENTRY_SEND_PII', 'false') == 'true'

  # Set environment
  config.environment = Rails.env

  # Configure release info from Docker tag or Git
  if ENV['GIT_COMMIT_SHA']
    config.release = ENV['GIT_COMMIT_SHA'][0..7]
  elsif ENV['APP_VERSION']
    config.release = ENV['APP_VERSION']
  end

  # Set server name for multi-instance environments
  config.server_name = ENV.fetch('SERVER_NAME', 'baffle-agent')

  # Filter out certain errors to reduce noise and add tags
  config.before_send = lambda do |event, hint|
    # Filter out 404 errors and other expected HTTP errors
    if event.contexts.dig(:response, :status_code) == 404
      nil
    # Filter out validation errors in development
    elsif Rails.env.development? && event.exception&.message&.include?("Validation failed")
      nil
    # Filter out specific noisy exceptions
    elsif %w[ActionController::RoutingError
             ActionController::InvalidAuthenticityToken
             ActionController::UnknownFormat
             ActionDispatch::Http::Parameters::ParseError].include?(event.exception&.class&.name)
      nil
    else
      # Add tags for better filtering in Sentry
      event.tags.merge!({
        ruby_version: RUBY_VERSION,
        rails_version: Rails.version,
        environment: Rails.env
      })
      event
    end
  end

  # Configure exception class exclusion
  config.excluded_exceptions += [
    'ActionController::RoutingError',
    'ActionController::InvalidAuthenticityToken',
    'CGI::Session::CookieStore::TamperedWithCookie',
    'ActionController::UnknownFormat',
    'ActionDispatch::Http::Parameters::ParseError',
    'Mongoid::Errors::DocumentNotFound'
  ]
end

# SolidQueue monitoring will be automatically handled by sentry-solid_queue gem

# Add correlation ID to Sentry context
ActiveSupport::Notifications.subscribe('action_controller.process_action') do |name, start, finish, id, payload|
  controller = payload[:controller]
  action = payload[:action]
  request_id = payload[:request]&.request_id

  if controller && action && request_id
    Sentry.set_context(:request, {
      correlation_id: request_id,
      controller: controller.controller_name,
      action: action.action_name,
      ip: request&.remote_ip
    })
  end
end

# Add ActiveJob context to all job transactions
ActiveSupport::Notifications.subscribe('perform.active_job') do |name, start, finish, id, payload|
  job = payload[:job]

  Sentry.configure_scope do |scope|
    scope.set_tag(:job_class, job.class.name)
    scope.set_tag(:job_queue, job.queue_name)
    scope.set_tag(:job_id, job.job_id)

    scope.set_context(:job, {
      job_id: job.job_id,
      job_class: job.class.name,
      queue_name: job.queue_name,
      arguments: job.arguments.to_s,
      enqueued_at: job.enqueued_at,
      executions: job.executions
    })
  end
end

# Monitor SolidQueue job failures
ActiveSupport::Notifications.subscribe('solid_queue.error') do |name, start, finish, id, payload|
  job = payload[:job]
  error = payload[:error]

  Sentry.with_scope do |scope|
    scope.set_tag(:job_class, job.class_name)
    scope.set_tag(:job_queue, job.queue_name)
    scope.set_context(:job, {
      job_id: job.active_job_id,
      arguments: job.arguments.to_s,
      queue_name: job.queue_name,
      created_at: job.created_at
    })
    scope.set_context(:error, {
      error_class: error.class.name,
      error_message: error.message
    })

    Sentry.capture_exception(error)
  end
end

# Set user context when available
if defined?(Current) && Current.user
  Sentry.set_user(id: Current.user.id, email: Current.user.email)
end

# Add application-specific context
app_version = begin
  File.read(Rails.root.join('VERSION')).strip
rescue
  ENV['APP_VERSION'] || ENV['GIT_COMMIT_SHA']&.[](0..7) || 'unknown'
end

Sentry.set_context('application', {
  name: 'BaffleHub',
  version: app_version,
  environment: Rails.env,
  database: ActiveRecord::Base.connection.adapter_name,
  queue_adapter: Rails.application.config.active_job.queue_adapter
})

Rails.logger.info "Sentry configured for environment: #{Rails.env}"