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

  import Phoenix.LiveViewTest
  import Berrypod.AccountsFixtures

  alias Berrypod.Analytics.{Buffer, Event}
  alias Berrypod.Repo

  setup do
    send(Buffer, :flush)
    :timer.sleep(50)
    Repo.delete_all(Event)

    user = user_fixture()
    %{user: user}
  end

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

  describe "analytics dashboard" do
    setup %{conn: conn, user: user} do
      %{conn: log_in_user(conn, user)}
    end

    test "renders the analytics page", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/admin/analytics")

      assert html =~ "Analytics"
      assert html =~ "Unique visitors"
      assert html =~ "Total pageviews"
      assert html =~ "Bounce rate"
      assert html =~ "Visit duration"
    end

    test "shows zero state with no data", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/admin/analytics")

      assert html =~ "No data for this period"
    end

    test "shows data when events exist", %{conn: conn} do
      now = DateTime.utc_now() |> DateTime.truncate(:second)

      Repo.insert_all(Event, [
        [
          id: Ecto.UUID.generate(),
          name: "pageview",
          pathname: "/",
          visitor_hash: :crypto.strong_rand_bytes(8),
          session_hash: :crypto.strong_rand_bytes(8),
          browser: "Chrome",
          os: "macOS",
          inserted_at: now
        ]
      ])

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

      assert has_element?(view, "[data-bars]")
    end

    test "changes period", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/analytics")

      html = render_click(view, "change_period", %{"period" => "7d"})
      assert html =~ "Analytics"
    end

    test "changes tab to sources", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/analytics")

      html = render_click(view, "change_tab", %{"tab" => "sources"})
      assert html =~ "Top sources"
      assert html =~ "Top referrers"
    end

    test "changes tab to countries", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/analytics")

      html = render_click(view, "change_tab", %{"tab" => "countries"})
      assert html =~ "Countries"
    end

    test "changes tab to devices", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/analytics")

      html = render_click(view, "change_tab", %{"tab" => "devices"})
      assert html =~ "Browsers"
      assert html =~ "Operating systems"
      assert html =~ "Screen sizes"
    end

    test "changes tab to funnel", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/analytics")

      html = render_click(view, "change_tab", %{"tab" => "funnel"})
      assert html =~ "Conversion funnel"
    end

    test "clicking a source adds a filter chip", %{conn: conn} do
      now = DateTime.utc_now() |> DateTime.truncate(:second)

      Repo.insert_all(Event, [
        [
          id: Ecto.UUID.generate(),
          name: "pageview",
          pathname: "/",
          visitor_hash: :crypto.strong_rand_bytes(8),
          session_hash: :crypto.strong_rand_bytes(8),
          referrer_source: "Google",
          inserted_at: now
        ]
      ])

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

      # Switch to sources tab and click the source
      render_click(view, "change_tab", %{"tab" => "sources"})

      html =
        render_click(view, "add_filter", %{"dimension" => "referrer_source", "value" => "Google"})

      assert html =~ "Source: Google"
      assert has_element?(view, "#analytics-filters")
    end

    test "removing a filter chip clears it", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/analytics")

      render_click(view, "add_filter", %{"dimension" => "country_code", "value" => "GB"})
      assert render(view) =~ "Country: United Kingdom"

      html = render_click(view, "remove_filter", %{"dimension" => "country_code"})
      refute html =~ "Country: United Kingdom"
    end

    test "clear all removes all filters", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/analytics")

      render_click(view, "add_filter", %{"dimension" => "country_code", "value" => "GB"})
      render_click(view, "add_filter", %{"dimension" => "browser", "value" => "Chrome"})
      assert render(view) =~ "Clear all"

      html = render_click(view, "clear_filters", %{})
      refute html =~ "Country: United Kingdom"
      refute html =~ "Browser: Chrome"
    end

    test "changing period preserves filters", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/analytics")

      render_click(view, "add_filter", %{"dimension" => "country_code", "value" => "GB"})
      html = render_click(view, "change_period", %{"period" => "7d"})

      assert html =~ "Country: United Kingdom"
    end
  end
end
