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

  alias Berrypod.Redirects.LinkScanner
  alias Berrypod.Pages

  describe "scan_page/1" do
    test "extracts URLs from hero block" do
      page = %{
        slug: "home",
        title: "Home",
        blocks: [
          %{
            "type" => "hero",
            "settings" => %{
              "cta_href" => "/collections/all",
              "secondary_cta_href" => "https://example.com"
            }
          }
        ]
      }

      links = LinkScanner.scan_page(page)
      urls = Enum.map(links, & &1.url) |> Enum.sort()

      assert "/collections/all" in urls
      assert "https://example.com" in urls
    end

    test "extracts URLs from button block" do
      page = %{
        slug: "test",
        title: "Test",
        blocks: [
          %{"type" => "button", "settings" => %{"href" => "/about"}}
        ]
      }

      [link] = LinkScanner.scan_page(page)
      assert link.url == "/about"
      assert link.type == :internal
    end

    test "extracts URLs from image_text block" do
      page = %{
        slug: "test",
        title: "Test",
        blocks: [
          %{"type" => "image_text", "settings" => %{"link_href" => "/products/mug"}}
        ]
      }

      [link] = LinkScanner.scan_page(page)
      assert link.url == "/products/mug"
    end

    test "extracts URLs from video_embed block" do
      page = %{
        slug: "test",
        title: "Test",
        blocks: [
          %{
            "type" => "video_embed",
            "settings" => %{"url" => "https://youtube.com/watch?v=abc"}
          }
        ]
      }

      [link] = LinkScanner.scan_page(page)
      assert link.url == "https://youtube.com/watch?v=abc"
      assert link.type == :external
    end

    test "skips empty strings, anchors, mailto, tel, and template vars" do
      page = %{
        slug: "test",
        title: "Test",
        blocks: [
          %{"type" => "hero", "settings" => %{"cta_href" => ""}},
          %{"type" => "button", "settings" => %{"href" => "#section"}},
          %{"type" => "button", "settings" => %{"href" => "mailto:hi@example.com"}},
          %{"type" => "button", "settings" => %{"href" => "tel:+441234567890"}},
          %{"type" => "button", "settings" => %{"href" => "{{unsubscribe_url}}"}}
        ]
      }

      assert LinkScanner.scan_page(page) == []
    end

    test "deduplicates URLs and groups sources" do
      page = %{
        slug: "home",
        title: "Home",
        blocks: [
          %{"type" => "hero", "settings" => %{"cta_href" => "/about"}},
          %{"type" => "button", "settings" => %{"href" => "/about"}}
        ]
      }

      links = LinkScanner.scan_page(page)
      assert length(links) == 1

      [link] = links
      assert link.url == "/about"
      assert length(link.sources) == 2
    end

    test "classifies internal and external URLs" do
      page = %{
        slug: "test",
        title: "Test",
        blocks: [
          %{"type" => "button", "settings" => %{"href" => "/about"}},
          %{"type" => "button", "settings" => %{"href" => "https://example.com"}}
        ]
      }

      links = LinkScanner.scan_page(page) |> Enum.sort_by(& &1.url)

      assert Enum.at(links, 0).type == :internal
      assert Enum.at(links, 1).type == :external
    end

    test "handles blocks with no settings" do
      page = %{
        slug: "test",
        title: "Test",
        blocks: [
          %{"type" => "spacer"},
          %{"type" => "divider", "settings" => %{}}
        ]
      }

      assert LinkScanner.scan_page(page) == []
    end
  end

  describe "scan_nav/0" do
    test "extracts URLs from header and footer nav" do
      {:ok, _} =
        Berrypod.Site.create_nav_item(%{
          location: "header",
          label: "Shop",
          url: "/collections/all",
          position: 0
        })

      {:ok, _} =
        Berrypod.Site.create_nav_item(%{
          location: "footer",
          label: "Privacy",
          url: "/privacy",
          position: 0
        })

      links = LinkScanner.scan_nav()
      urls = Enum.map(links, & &1.url)

      assert "/collections/all" in urls
      assert "/privacy" in urls
    end

    test "returns empty when no nav configured" do
      assert LinkScanner.scan_nav() == []
    end
  end

  describe "find_sources/1" do
    test "finds page blocks using a URL" do
      # Save a custom page (not system page, avoids ETS cache issues)
      {:ok, _page} =
        Pages.create_custom_page(%{
          slug: "test-link-page",
          title: "Test page",
          blocks: [
            %{"type" => "hero", "settings" => %{"cta_href" => "/test-unique-link"}},
            %{"type" => "button", "settings" => %{"href" => "/about"}}
          ]
        })

      sources = LinkScanner.find_sources("/test-unique-link")

      assert length(sources) == 1
      [source] = sources
      assert source.type == "page_block"
      assert source.id == "test-link-page"
      assert source.label =~ "hero"
      assert source.edit_path == "/admin/pages/test-link-page"
    end

    test "finds nav items using a URL" do
      {:ok, _} =
        Berrypod.Site.create_nav_item(%{
          location: "header",
          label: "Shop",
          url: "/test-nav-link",
          position: 0
        })

      sources = LinkScanner.find_sources("/test-nav-link")

      assert length(sources) == 1
      [source] = sources
      assert source.type == "nav_item"
      assert source.label =~ "Header nav"
      assert source.edit_path == "/?edit=site"
    end

    test "returns empty for unused URL" do
      assert LinkScanner.find_sources("/nonexistent") == []
    end
  end
end
