defmodule Berrypod.Redirects.LinkCheckerTest do
  use Berrypod.DataCase, async: true

  alias Berrypod.Redirects.LinkChecker

  describe "check_internal/1" do
    test "static routes are valid" do
      assert :ok = LinkChecker.check_internal("/")
      assert :ok = LinkChecker.check_internal("/about")
      assert :ok = LinkChecker.check_internal("/contact")
      assert :ok = LinkChecker.check_internal("/delivery")
      assert :ok = LinkChecker.check_internal("/privacy")
      assert :ok = LinkChecker.check_internal("/terms")
      assert :ok = LinkChecker.check_internal("/cart")
      assert :ok = LinkChecker.check_internal("/search")
      assert :ok = LinkChecker.check_internal("/collections/all")
    end

    test "collection routes are always valid" do
      assert :ok = LinkChecker.check_internal("/collections/nonexistent")
    end

    test "existing product slug is valid" do
      conn = Berrypod.ProductsFixtures.provider_connection_fixture()

      Berrypod.Products.create_product(%{
        provider_connection_id: conn.id,
        provider_product_id: "checker_test_1",
        title: "Test Product",
        slug: "test-checker-product",
        status: "active",
        visible: true,
        in_stock: true,
        cheapest_price: 1000
      })

      assert :ok = LinkChecker.check_internal("/products/test-checker-product")
    end

    test "nonexistent product slug is broken" do
      assert {:error, "product not found"} =
               LinkChecker.check_internal("/products/nonexistent-product")
    end

    test "existing custom page is valid" do
      {:ok, _page} =
        Berrypod.Pages.create_custom_page(%{
          slug: "checker-test-page",
          title: "Test",
          blocks: []
        })

      assert :ok = LinkChecker.check_internal("/checker-test-page")
    end

    test "nonexistent custom page is broken" do
      assert {:error, "page not found"} =
               LinkChecker.check_internal("/totally-nonexistent-page")
    end
  end

  describe "check_external/1" do
    setup do
      # Use a function plug to stub HTTP responses in tests
      Application.put_env(:berrypod, :link_checker_plug, &__MODULE__.test_plug/1)
      on_exit(fn -> Application.delete_env(:berrypod, :link_checker_plug) end)
      :ok
    end

    test "healthy URL returns :ok" do
      assert :ok = LinkChecker.check_external("http://test/healthy")
    end

    test "404 URL returns error with status" do
      assert {:error, 404, "not found"} = LinkChecker.check_external("http://test/not-found")
    end

    test "500 URL returns error with status" do
      assert {:error, 500, "server error"} =
               LinkChecker.check_external("http://test/server-error")
    end

    test "405 falls back to GET" do
      assert :ok = LinkChecker.check_external("http://test/head-not-allowed")
    end

    # Test plug that simulates various responses
    def test_plug(conn) do
      case conn.request_path do
        "/healthy" ->
          Plug.Conn.send_resp(conn, 200, "OK")

        "/not-found" ->
          Plug.Conn.send_resp(conn, 404, "Not Found")

        "/server-error" ->
          Plug.Conn.send_resp(conn, 500, "Error")

        "/head-not-allowed" ->
          if conn.method == "HEAD" do
            Plug.Conn.send_resp(conn, 405, "Method Not Allowed")
          else
            Plug.Conn.send_resp(conn, 200, "OK")
          end

        _ ->
          Plug.Conn.send_resp(conn, 404, "Not Found")
      end
    end
  end
end
