defmodule SimpleshopTheme.Webhooks do
  @moduledoc """
  Handles incoming webhook events from POD providers.
  """

  alias SimpleshopTheme.Orders
  alias SimpleshopTheme.Orders.OrderNotifier
  alias SimpleshopTheme.Products
  alias SimpleshopTheme.Sync.ProductSyncWorker
  alias SimpleshopTheme.Webhooks.ProductDeleteWorker

  require Logger

  @doc """
  Handles a Printify webhook event.

  Returns :ok or {:ok, job} on success, {:error, reason} on failure.
  """

  # --- Product events ---

  def handle_printify_event("product:updated", %{"id" => _product_id}) do
    enqueue_product_sync()
  end

  def handle_printify_event("product:publish:started", %{"id" => _product_id}) do
    enqueue_product_sync()
  end

  def handle_printify_event("product:deleted", %{"id" => product_id}) do
    ProductDeleteWorker.enqueue(product_id)
  end

  # --- Order events ---

  def handle_printify_event("order:sent-to-production", resource) do
    with {:ok, order} <- find_order_from_resource(resource) do
      Orders.update_fulfilment(order, %{
        fulfilment_status: "processing",
        provider_status: "in-production"
      })
    end
  end

  def handle_printify_event("order:shipment:created", resource) do
    shipment = extract_shipment(resource)

    with {:ok, order} <- find_order_from_resource(resource),
         {:ok, updated_order} <-
           Orders.update_fulfilment(order, %{
             fulfilment_status: "shipped",
             provider_status: "shipped",
             tracking_number: shipment.tracking_number,
             tracking_url: shipment.tracking_url,
             shipped_at: DateTime.utc_now() |> DateTime.truncate(:second)
           }) do
      OrderNotifier.deliver_shipping_notification(updated_order)
      {:ok, updated_order}
    end
  end

  def handle_printify_event("order:shipment:delivered", resource) do
    with {:ok, order} <- find_order_from_resource(resource) do
      Orders.update_fulfilment(order, %{
        fulfilment_status: "delivered",
        provider_status: "delivered",
        delivered_at: DateTime.utc_now() |> DateTime.truncate(:second)
      })
    end
  end

  # --- Catch-all ---

  def handle_printify_event("shop:disconnected", _resource) do
    Logger.warning("Printify shop disconnected - manual intervention needed")
    :ok
  end

  def handle_printify_event(event_type, _resource) do
    Logger.info("Ignoring unhandled Printify event: #{event_type}")
    :ok
  end

  # --- Private helpers ---

  defp enqueue_product_sync do
    case Products.get_provider_connection_by_type("printify") do
      nil -> {:error, :no_connection}
      conn -> ProductSyncWorker.enqueue(conn.id)
    end
  end

  # Printify order webhooks include external_id (our order_number) in the resource
  defp find_order_from_resource(%{"external_id" => external_id}) when is_binary(external_id) do
    case Orders.get_order_by_number(external_id) do
      nil ->
        Logger.warning("Order webhook: no order found for external_id=#{external_id}")
        {:error, :order_not_found}

      order ->
        {:ok, order}
    end
  end

  defp find_order_from_resource(resource) do
    Logger.warning("Order webhook: missing external_id in resource #{inspect(resource)}")
    {:error, :missing_external_id}
  end

  defp extract_shipment(resource) do
    shipments = resource["shipments"] || []
    shipment = List.last(shipments) || %{}

    %{
      tracking_number: shipment["tracking_number"],
      tracking_url: shipment["tracking_url"]
    }
  end
end
