defmodule Towerops.Workers.GaiiaSyncWorker do
  @moduledoc """
  Oban cron worker that syncs Gaiia data for all enabled integrations.

  Runs every 15 minutes. For each org with an enabled Gaiia integration,
  checks if enough time has elapsed since the last sync (based on the
  integration's sync_interval_minutes), then calls Gaiia.Sync.sync_organization/1.
  """
  use Oban.Worker, queue: :maintenance

  alias Towerops.Gaiia.Sync
  alias Towerops.Integrations

  require Logger

  @impl Oban.Worker
  def perform(%Oban.Job{}) do
    integrations = Integrations.list_enabled_integrations("gaiia")

    results = Enum.map(integrations, &sync_integration/1)

    synced = Enum.count(results, &match?({:ok, _}, &1))
    failed = Enum.count(results, &match?({:error, _}, &1))
    skipped = Enum.count(results, &(&1 == :skipped))

    if synced > 0 or failed > 0 do
      Logger.info("Gaiia sync batch: #{synced} synced, #{failed} failed, #{skipped} skipped")
    end

    :ok
  end

  defp sync_integration(integration) do
    if should_sync?(integration) do
      case Sync.sync_organization(integration) do
        {:ok, result} ->
          Logger.info("Gaiia sync completed for org #{integration.organization_id}: #{inspect(result)}")

          {:ok, result}

        {:error, reason} ->
          Logger.error("Gaiia sync failed for org #{integration.organization_id}: #{inspect(reason)}")

          {:error, reason}
      end
    else
      :skipped
    end
  end

  defp should_sync?(integration) do
    case integration.last_synced_at do
      nil ->
        true

      last_synced_at ->
        interval_seconds = (integration.sync_interval_minutes || 15) * 60
        elapsed = DateTime.diff(DateTime.utc_now(), last_synced_at, :second)
        elapsed >= interval_seconds
    end
  end
end
