# frozen_string_literal: true

class <%= class_name %>ActivitiesFetchJob < ApplicationJob
  include <%= class_name %>Account::DataHelpers

  queue_as :default

  MAX_RETRIES = 6
  RETRY_INTERVAL = 10.seconds

  sidekiq_options lock: :until_executed,
                  lock_args_method: ->(args) { args.first },
                  on_conflict: :log

  def perform(<%= file_name %>_account, start_date: nil, retry_count: 0)
    @<%= file_name %>_account = <%= file_name %>_account
    @start_date = start_date || 3.years.ago.to_date
    @retry_count = retry_count

    return clear_pending_flag unless valid_for_fetch?

    fetch_and_process_activities
  rescue => e
    Rails.logger.error("<%= class_name %>ActivitiesFetchJob error: #{e.class} - #{e.message}")
    clear_pending_flag
    raise
  end

  private

    def valid_for_fetch?
      return false unless @<%= file_name %>_account
      return false unless @<%= file_name %>_account.<%= file_name %>_item
      return false unless @<%= file_name %>_account.current_account
      true
    end

    def fetch_and_process_activities
      activities = fetch_activities

      if activities.blank? && @retry_count < MAX_RETRIES
        schedule_retry
        return
      end

      if activities.any?
        merged = merge_activities(existing_activities, activities)
        @<%= file_name %>_account.upsert_activities_snapshot!(merged)
        @<%= file_name %>_account.update!(last_activities_sync: Time.current)

        <%= class_name %>Account::ActivitiesProcessor.new(@<%= file_name %>_account).process
      end

      clear_pending_flag
      broadcast_updates
    end

    def fetch_activities
      provider = @<%= file_name %>_account.<%= file_name %>_item.<%= file_name %>_provider
      credentials = @<%= file_name %>_account.<%= file_name %>_item.<%= file_name %>_credentials

      return [] unless provider && credentials

      # TODO: Implement API call to fetch activities
      # provider.get_activities(
      #   account_id: @<%= file_name %>_account.<%= file_name %>_account_id,
      #   start_date: @start_date,
      #   end_date: Date.current,
      #   **credentials
      # )
      []
    rescue Provider::<%= class_name %>::AuthenticationError
      # Re-raise auth errors - they need immediate attention
      raise
    rescue => e
      # Transient errors trigger retry via blank response
      Rails.logger.error("<%= class_name %>ActivitiesFetchJob - API error: #{e.message}")
      []
    end

    def existing_activities
      @<%= file_name %>_account.raw_activities_payload || []
    end

    def merge_activities(existing, new_activities)
      by_id = {}
      existing.each { |a| by_id[activity_key(a)] = a }
      new_activities.each do |a|
        activity_hash = sdk_object_to_hash(a)
        by_id[activity_key(activity_hash)] = activity_hash
      end
      by_id.values
    end

    def activity_key(activity)
      activity = activity.with_indifferent_access if activity.is_a?(Hash)
      activity[:id] || activity["id"] ||
        [ activity[:date], activity[:type], activity[:amount], activity[:symbol] ].join("-")
    end

    def schedule_retry
      Rails.logger.info(
        "<%= class_name %>ActivitiesFetchJob - No activities found, scheduling retry " \
        "#{@retry_count + 1}/#{MAX_RETRIES} in #{RETRY_INTERVAL.to_i}s"
      )

      self.class.set(wait: RETRY_INTERVAL).perform_later(
        @<%= file_name %>_account,
        start_date: @start_date,
        retry_count: @retry_count + 1
      )
    end

    def clear_pending_flag
      @<%= file_name %>_account.update!(activities_fetch_pending: false)
    end

    def broadcast_updates
      @<%= file_name %>_account.current_account&.broadcast_sync_complete
      @<%= file_name %>_account.<%= file_name %>_item&.broadcast_replace_to(
        @<%= file_name %>_account.<%= file_name %>_item.family,
        target: "<%= file_name %>_item_#{@<%= file_name %>_account.<%= file_name %>_item.id}",
        partial: "<%= file_name %>_items/<%= file_name %>_item"
      )
    rescue => e
      Rails.logger.warn("<%= class_name %>ActivitiesFetchJob - Broadcast failed: #{e.message}")
    end
end
