defmodule BerrypodWeb.Admin.ProductsTest do
  use BerrypodWeb.ConnCase, async: false

  import Phoenix.LiveViewTest
  import Berrypod.AccountsFixtures
  import Berrypod.ProductsFixtures

  setup do
    user = user_fixture()
    conn = provider_connection_fixture(%{provider_type: "printify", name: "Test Shop"})
    product = complete_product_fixture(%{provider_connection: conn})

    %{user: user, connection: conn, product: product}
  end

  describe "unauthenticated" do
    test "product list redirects to login", %{conn: conn} do
      {:error, redirect} = live(conn, ~p"/admin/products")
      assert {:redirect, %{to: path}} = redirect
      assert path == ~p"/users/log-in"
    end

    test "product detail redirects to login", %{conn: conn, product: product} do
      {:error, redirect} = live(conn, ~p"/admin/products/#{product}")
      assert {:redirect, %{to: path}} = redirect
      assert path == ~p"/users/log-in"
    end
  end

  describe "product list" do
    setup %{conn: conn, user: user} do
      %{conn: log_in_user(conn, user)}
    end

    test "renders product list", %{conn: conn, product: product} do
      {:ok, _view, html} = live(conn, ~p"/admin/products")

      assert html =~ "Products"
      assert html =~ product.title
    end

    test "shows provider badge", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/admin/products")

      assert html =~ "Printify"
    end

    test "shows category", %{conn: conn, product: product} do
      {:ok, _view, html} = live(conn, ~p"/admin/products")

      assert html =~ product.category
    end

    test "links to product detail", %{conn: conn, product: product} do
      {:ok, _view, html} = live(conn, ~p"/admin/products")

      assert html =~ ~p"/admin/products/#{product}"
    end

    test "toggle visibility updates product", %{conn: conn, product: product} do
      {:ok, view, _html} = live(conn, ~p"/admin/products")

      assert product.visible

      view
      |> element("button[phx-value-id='#{product.id}']")
      |> render_click()

      updated = Berrypod.Products.get_product(product.id)
      refute updated.visible
    end

    test "filters by visibility", %{conn: conn, product: product} do
      Berrypod.Products.update_storefront(product, %{visible: false})

      {:ok, view, _html} = live(conn, ~p"/admin/products")

      html =
        view
        |> element("form")
        |> render_change(%{"visibility" => "hidden"})

      assert html =~ product.title

      html =
        view
        |> element("form")
        |> render_change(%{"visibility" => "visible"})

      refute html =~ product.title
    end

    test "filters by category", %{conn: conn, product: product} do
      {:ok, view, _html} = live(conn, ~p"/admin/products")

      html =
        view
        |> element("form")
        |> render_change(%{"category" => product.category})

      assert html =~ product.title

      html =
        view
        |> element("form")
        |> render_change(%{"category" => "Nonexistent"})

      refute html =~ product.title
    end

    test "sorts by name", %{conn: conn, product: product} do
      {:ok, view, _html} = live(conn, ~p"/admin/products")

      html =
        view
        |> element("form")
        |> render_change(%{"sort" => "name_asc"})

      assert html =~ product.title
    end

    test "shows empty state when no products", %{conn: conn, product: product} do
      Berrypod.Products.delete_product(product)

      {:ok, _view, html} = live(conn, ~p"/admin/products")

      assert html =~ "No products yet"
      assert html =~ "providers page"
    end
  end

  describe "product detail" do
    setup %{conn: conn, user: user} do
      %{conn: log_in_user(conn, user)}
    end

    test "renders product detail", %{conn: conn, product: product} do
      {:ok, _view, html} = live(conn, ~p"/admin/products/#{product}")

      assert html =~ product.title
      assert html =~ "Details"
      assert html =~ "Storefront controls"
      assert html =~ "Variants"
    end

    test "shows provider link", %{conn: conn, product: product} do
      {:ok, _view, html} = live(conn, ~p"/admin/products/#{product}")

      assert html =~ "Edit on Printify"
    end

    test "shows view on shop link", %{conn: conn, product: product} do
      {:ok, _view, html} = live(conn, ~p"/admin/products/#{product}")

      assert html =~ ~p"/products/#{product.slug}"
    end

    test "shows variant details", %{conn: conn, product: product} do
      {:ok, _view, html} = live(conn, ~p"/admin/products/#{product}")

      assert html =~ "£25.00"
    end

    test "saves storefront changes", %{conn: conn, product: product} do
      {:ok, view, _html} = live(conn, ~p"/admin/products/#{product}")

      view
      |> element("form")
      |> render_submit(%{"product" => %{"visible" => "false", "category" => "New Category"}})

      updated = Berrypod.Products.get_product(product.id)
      refute updated.visible
      assert updated.category == "New Category"
    end

    test "redirects on not found", %{conn: conn} do
      {:error, {:live_redirect, %{to: path}}} =
        live(conn, "/admin/products/00000000-0000-0000-0000-000000000000")

      assert path == "/admin/products"
    end

    test "back link navigates to list", %{conn: conn, product: product} do
      {:ok, _view, html} = live(conn, ~p"/admin/products/#{product}")

      assert html =~ ~s(href="/admin/products")
      assert html =~ "Products"
    end
  end
end
