defmodule BerrypodWeb.Shop.CartTest do
  use BerrypodWeb.ConnCase, async: false

  import Phoenix.LiveViewTest
  import Berrypod.AccountsFixtures

  alias Berrypod.ProductsFixtures

  setup do
    user_fixture()
    {:ok, _} = Berrypod.Settings.set_site_live(true)
    :ok
  end

  defp create_cart_with_product(_context) do
    product = ProductsFixtures.complete_product_fixture(%{title: "Test Art Print"})
    variant = List.first(product.variants)
    %{product: product, variant: variant}
  end

  defp conn_with_cart(conn, variant_id, qty \\ 1) do
    conn
    |> Phoenix.ConnTest.init_test_session(%{"cart" => [{variant_id, qty}]})
  end

  describe "Empty cart" do
    test "renders empty cart state", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/cart")

      assert html =~ "Your basket"
      assert html =~ "Your basket is empty"
    end

    test "shows continue shopping link when empty", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/cart")

      assert html =~ "Continue shopping"
    end
  end

  describe "Cart with items" do
    setup [:create_cart_with_product]

    test "displays cart item name", %{conn: conn, product: product, variant: variant} do
      {:ok, _view, html} = conn |> conn_with_cart(variant.id) |> live(~p"/cart")

      assert html =~ product.title
    end

    test "displays order summary", %{conn: conn, variant: variant} do
      {:ok, _view, html} = conn |> conn_with_cart(variant.id) |> live(~p"/cart")

      assert html =~ "Order summary"
      assert html =~ "Subtotal"
    end

    test "displays formatted subtotal", %{conn: conn, variant: variant} do
      {:ok, _view, html} = conn |> conn_with_cart(variant.id) |> live(~p"/cart")

      assert html =~ Berrypod.Cart.format_price(variant.price)
    end

    test "displays checkout button", %{conn: conn, variant: variant} do
      {:ok, _view, html} = conn |> conn_with_cart(variant.id) |> live(~p"/cart")

      assert html =~ "Checkout"
    end

    test "incrementing quantity updates the display", %{
      conn: conn,
      variant: variant
    } do
      {:ok, view, _html} = conn |> conn_with_cart(variant.id) |> live(~p"/cart")

      html =
        view
        |> form("#main-content form[phx-submit='update_quantity_form']")
        |> render_submit(%{"quantity" => "2"})

      assert html =~ "Quantity updated to 2"
    end

    test "decrementing to zero removes the item", %{
      conn: conn,
      variant: variant
    } do
      {:ok, view, _html} = conn |> conn_with_cart(variant.id) |> live(~p"/cart")

      html =
        view
        |> form("#main-content form[phx-submit='update_quantity_form']")
        |> render_submit(%{"quantity" => "0"})

      assert html =~ "Your basket is empty"
    end

    test "remove button removes the item", %{conn: conn, variant: variant} do
      {:ok, view, _html} = conn |> conn_with_cart(variant.id) |> live(~p"/cart")

      html =
        view
        |> form("#main-content form[phx-submit='remove_item_form']")
        |> render_submit()

      assert html =~ "Your basket is empty"
    end
  end

  describe "no-JS fallback" do
    setup [:create_cart_with_product]

    test "country selector form has action for no-JS submission", %{
      conn: conn,
      variant: variant
    } do
      # Insert a shipping rate so the country selector renders
      now = DateTime.utc_now() |> DateTime.truncate(:second)
      pc = Berrypod.ProductsFixtures.provider_connection_fixture()

      Berrypod.Repo.insert_all(Berrypod.Shipping.ShippingRate, [
        [
          blueprint_id: 1,
          print_provider_id: 1,
          country_code: "GB",
          first_item_cost: 399,
          additional_item_cost: 100,
          provider_connection_id: pc.id,
          inserted_at: now,
          updated_at: now
        ]
      ])

      {:ok, view, _html} = conn |> conn_with_cart(variant.id) |> live(~p"/cart")

      assert has_element?(view, "form[action='/cart/country'][method='post']")
    end
  end

  describe "Cart page title" do
    test "page title is Cart", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/cart")

      assert html =~ ~r/Cart\s*·\s*Store Name/
    end
  end
end
