defmodule Berrypod.OrdersFixtures do
  @moduledoc """
  Test helpers for creating orders.
  """

  alias Berrypod.Orders

  import Berrypod.ProductsFixtures

  def order_fixture(attrs \\ %{}) do
    attrs = Enum.into(attrs, %{})

    items = [
      %{
        variant_id: Map.get(attrs, :variant_id, "var_#{System.unique_integer([:positive])}"),
        name: Map.get(attrs, :product_name, "Test product"),
        variant: Map.get(attrs, :variant_title, "Red / Large"),
        price: Map.get(attrs, :unit_price, 1999),
        quantity: Map.get(attrs, :quantity, 1)
      }
    ]

    order_attrs = %{
      items: items,
      customer_email: Map.get(attrs, :customer_email, "customer@example.com"),
      currency: Map.get(attrs, :currency, "gbp")
    }

    {:ok, order} = Orders.create_order(order_attrs)

    # Apply shipping address if provided
    order =
      case attrs[:shipping_address] do
        nil ->
          order

        addr ->
          {:ok, order} = Orders.update_order(order, %{shipping_address: addr})
          order
      end

    case attrs[:payment_status] do
      "paid" ->
        {:ok, order} = Orders.mark_paid(order, "pi_test_#{System.unique_integer([:positive])}")
        order

      "failed" ->
        {:ok, order} = Orders.mark_failed(order)
        order

      _ ->
        order
    end
  end

  @doc """
  Creates a paid order with real product variants in the DB,
  so enrich_items/1 can look up provider IDs. Also sets a shipping
  address matching Stripe's format.

  Returns `{order, variant, product, conn}`.
  """
  def paid_order_with_products_fixture(attrs \\ %{}) do
    attrs = Enum.into(attrs, %{})
    conn = provider_connection_fixture(%{provider_type: "printify"})
    product = product_fixture(%{provider_connection: conn})
    variant = product_variant_fixture(%{product: product})

    shipping =
      Map.get(attrs, :shipping_address, %{
        "name" => "Jane Doe",
        "line1" => "42 Test Street",
        "line2" => nil,
        "city" => "London",
        "postal_code" => "SW1A 1AA",
        "state" => nil,
        "country" => "GB"
      })

    order =
      order_fixture(%{
        variant_id: variant.id,
        payment_status: "paid",
        shipping_address: shipping,
        customer_email: Map.get(attrs, :customer_email, "buyer@example.com")
      })

    {order, variant, product, conn}
  end

  @doc """
  Creates a submitted order (has provider_order_id set).
  Returns `{order, variant, product, conn}`.
  """
  def submitted_order_fixture(attrs \\ %{}) do
    {order, variant, product, conn} = paid_order_with_products_fixture(attrs)

    attrs = Enum.into(attrs, %{})

    {:ok, order} =
      Orders.update_fulfilment(order, %{
        fulfilment_status: "submitted",
        provider_order_id:
          Map.get(attrs, :provider_order_id, "printify_#{System.unique_integer([:positive])}"),
        submitted_at: DateTime.utc_now() |> DateTime.truncate(:second)
      })

    {order, variant, product, conn}
  end
end
