# frozen_string_literal: true

class Users::ImportData::Notifications
  BATCH_SIZE = 1000

  def initialize(user, notifications_data)
    @user = user
    @notifications_data = notifications_data
  end

  def call
    return 0 unless notifications_data.is_a?(Array)

    Rails.logger.info "Importing #{notifications_data.size} notifications for user: #{user.email}"

    valid_notifications = filter_and_prepare_notifications

    if valid_notifications.empty?
      Rails.logger.info 'Notifications import completed. Created: 0'
      return 0
    end

    deduplicated_notifications = filter_existing_notifications(valid_notifications)

    if deduplicated_notifications.size < valid_notifications.size
      Rails.logger.debug "Skipped #{valid_notifications.size - deduplicated_notifications.size} duplicate notifications"
    end

    total_created = bulk_import_notifications(deduplicated_notifications)

    Rails.logger.info "Notifications import completed. Created: #{total_created}"
    total_created
  end

  private

  attr_reader :user, :notifications_data

  def filter_and_prepare_notifications
    valid_notifications = []
    skipped_count = 0

    notifications_data.each do |notification_data|
      next unless notification_data.is_a?(Hash)

      unless valid_notification_data?(notification_data)
        skipped_count += 1
        next
      end

      prepared_attributes = prepare_notification_attributes(notification_data)
      valid_notifications << prepared_attributes if prepared_attributes
    end

    if skipped_count > 0
      Rails.logger.warn "Skipped #{skipped_count} notifications with invalid or missing required data"
    end

    valid_notifications
  end

  def prepare_notification_attributes(notification_data)
    attributes = notification_data.except('updated_at')

    attributes['user_id'] = user.id

    unless attributes['created_at'].present?
      attributes['created_at'] = Time.current
    end

    attributes['updated_at'] = Time.current

    attributes.symbolize_keys
  rescue StandardError => e
    Rails.logger.error "Failed to prepare notification attributes: #{e.message}"
    Rails.logger.error "Notification data: #{notification_data.inspect}"
    nil
  end

  def filter_existing_notifications(notifications)
    return notifications if notifications.empty?

    existing_notifications_lookup = {}
    user.notifications.select(:title, :content, :created_at, :kind).each do |notification|
      primary_key = [notification.title.strip, notification.content.strip]

      exact_key = [notification.title.strip, notification.content.strip, normalize_timestamp(notification.created_at)]

      existing_notifications_lookup[primary_key] = true
      existing_notifications_lookup[exact_key] = true
    end

    filtered_notifications = notifications.reject do |notification|
      title = notification[:title]&.strip
      content = notification[:content]&.strip

      primary_key = [title, content]
      exact_key = [title, content, normalize_timestamp(notification[:created_at])]

      if existing_notifications_lookup[primary_key] || existing_notifications_lookup[exact_key]
        Rails.logger.debug "Notification already exists: #{notification[:title]}"
        true
      else
        false
      end
    end

    filtered_notifications
  end

  def normalize_timestamp(timestamp)
    case timestamp
    when String then Time.parse(timestamp).to_i
    when Time, DateTime then timestamp.to_i
    else
      timestamp.to_s
    end
  rescue StandardError => e
    Rails.logger.debug "Failed to normalize timestamp #{timestamp}: #{e.message}"
    timestamp.to_s
  end

  def bulk_import_notifications(notifications)
    total_created = 0

    notifications.each_slice(BATCH_SIZE) do |batch|
      begin
        result = Notification.upsert_all(
          batch,
          returning: %w[id],
          on_duplicate: :skip
        )

        batch_created = result.count
        total_created += batch_created

        Rails.logger.debug "Processed batch of #{batch.size} notifications, created #{batch_created}, total created: #{total_created}"

      rescue StandardError => e
        Rails.logger.error "Failed to process notification batch: #{e.message}"
        Rails.logger.error "Batch size: #{batch.size}"
        Rails.logger.error "Backtrace: #{e.backtrace.first(3).join('\n')}"
      end
    end

    total_created
  end

  def valid_notification_data?(notification_data)
    return false unless notification_data.is_a?(Hash)

    unless notification_data['title'].present?
      Rails.logger.error "Failed to create notification: Validation failed: Title can't be blank"
      return false
    end

    unless notification_data['content'].present?
      Rails.logger.error "Failed to create notification: Validation failed: Content can't be blank"
      return false
    end

    true
  rescue StandardError => e
    Rails.logger.debug "Notification validation failed: #{e.message} for data: #{notification_data.inspect}"
    false
  end
end
