defmodule SimpleshopTheme.Providers.Provider do @moduledoc """ Behaviour for POD provider integrations. Each provider (Printify, Gelato, Prodigi, etc.) implements this behaviour to provide a consistent interface for: - Testing connections - Fetching products - Submitting orders - Tracking order status ## Data Normalization Providers return normalized data structures: - Products are maps with keys: `title`, `description`, `provider_product_id`, `images`, `variants`, `category`, `provider_data` - Variants are maps with keys: `provider_variant_id`, `title`, `sku`, `price`, `cost`, `options`, `is_enabled`, `is_available` - Images are maps with keys: `src`, `position`, `alt` """ alias SimpleshopTheme.Products.ProviderConnection @doc """ Returns the provider type identifier (e.g., "printify", "gelato"). """ @callback provider_type() :: String.t() @doc """ Tests the connection to the provider. Returns `{:ok, info}` with provider-specific info (e.g., shop name) or `{:error, reason}` if the connection fails. """ @callback test_connection(ProviderConnection.t()) :: {:ok, map()} | {:error, term()} @doc """ Fetches all products from the provider. Returns a list of normalized product maps. """ @callback fetch_products(ProviderConnection.t()) :: {:ok, [map()]} | {:error, term()} @doc """ Submits an order to the provider for fulfillment. Returns `{:ok, %{provider_order_id: String.t()}}` on success. """ @callback submit_order(ProviderConnection.t(), order :: map()) :: {:ok, %{provider_order_id: String.t()}} | {:error, term()} @doc """ Gets the current status of an order from the provider. """ @callback get_order_status(ProviderConnection.t(), provider_order_id :: String.t()) :: {:ok, map()} | {:error, term()} @doc """ Returns the provider module for a given provider type. """ def for_type("printify"), do: {:ok, SimpleshopTheme.Providers.Printify} def for_type("gelato"), do: {:error, :not_implemented} def for_type("prodigi"), do: {:error, :not_implemented} def for_type("printful"), do: {:error, :not_implemented} def for_type(type), do: {:error, {:unknown_provider, type}} @doc """ Returns the provider module for a provider connection. """ def for_connection(%ProviderConnection{provider_type: type}) do for_type(type) end end