# frozen_string_literal: true

class <%= class_name %>Item::Syncer
  include SyncStats::Collector

  attr_reader :<%= file_name %>_item

  def initialize(<%= file_name %>_item)
    @<%= file_name %>_item = <%= file_name %>_item
  end

  def perform_sync(sync)
    Rails.logger.info "<%= class_name %>Item::Syncer - Starting sync for item #{<%= file_name %>_item.id}"

    # Phase 1: Import data from provider API
    sync.update!(status_text: I18n.t("<%= file_name %>_items.sync.status.importing")) if sync.respond_to?(:status_text)
    <%= file_name %>_item.import_latest_<%= file_name %>_data(sync: sync)

    # Phase 2: Collect setup statistics
    finalize_setup_counts(sync)

    # Phase 3: Process data for linked accounts
    linked_<%= file_name %>_accounts = <%= file_name %>_item.linked_<%= file_name %>_accounts.includes(account_provider: :account)
    if linked_<%= file_name %>_accounts.any?
      sync.update!(status_text: I18n.t("<%= file_name %>_items.sync.status.processing")) if sync.respond_to?(:status_text)
      mark_import_started(sync)
      <%= file_name %>_item.process_accounts

      # Phase 4: Schedule balance calculations
      sync.update!(status_text: I18n.t("<%= file_name %>_items.sync.status.calculating")) if sync.respond_to?(:status_text)
      <%= file_name %>_item.schedule_account_syncs(
        parent_sync: sync,
        window_start_date: sync.window_start_date,
        window_end_date: sync.window_end_date
      )

      # Phase 5: Collect statistics
      account_ids = linked_<%= file_name %>_accounts.filter_map { |pa| pa.current_account&.id }
<% if investment_provider? -%>
      collect_transaction_stats(sync, account_ids: account_ids, source: "<%= file_name %>")
      collect_trades_stats(sync, account_ids: account_ids, source: "<%= file_name %>")
      collect_holdings_stats(sync, holdings_count: count_holdings, label: "processed")
<% else -%>
      collect_transaction_stats(sync, account_ids: account_ids, source: "<%= file_name %>")
<% end -%>
    end

    # Mark sync health
    collect_health_stats(sync, errors: nil)
  rescue Provider::<%= class_name %>::AuthenticationError => e
    <%= file_name %>_item.update!(status: :requires_update)
    collect_health_stats(sync, errors: [ { message: e.message, category: "auth_error" } ])
    raise
  rescue => e
    collect_health_stats(sync, errors: [ { message: e.message, category: "sync_error" } ])
    raise
  end

  # Public: called by Sync after finalization
  def perform_post_sync
    # Override for post-sync cleanup if needed
  end

  private
<% if investment_provider? -%>

    def count_holdings
      <%= file_name %>_item.linked_<%= file_name %>_accounts.sum { |pa| Array(pa.raw_holdings_payload).size }
    end
<% end -%>

    def mark_import_started(sync)
      # Mark that we're now processing imported data
      sync.update!(status_text: I18n.t("<%= file_name %>_items.sync.status.importing_data")) if sync.respond_to?(:status_text)
    end

    def finalize_setup_counts(sync)
      sync.update!(status_text: I18n.t("<%= file_name %>_items.sync.status.checking_setup")) if sync.respond_to?(:status_text)

      unlinked_count = <%= file_name %>_item.unlinked_accounts_count

      if unlinked_count > 0
        <%= file_name %>_item.update!(pending_account_setup: true)
        sync.update!(status_text: I18n.t("<%= file_name %>_items.sync.status.needs_setup", count: unlinked_count)) if sync.respond_to?(:status_text)
      else
        <%= file_name %>_item.update!(pending_account_setup: false)
      end

      # Collect setup stats
      collect_setup_stats(sync, provider_accounts: <%= file_name %>_item.<%= file_name %>_accounts)
    end
end
