defmodule BerrypodWeb.NewsletterControllerTest do
  use BerrypodWeb.ConnCase, async: true

  alias Berrypod.Newsletter
  alias Berrypod.Newsletter.Subscriber
  alias Berrypod.Repo

  describe "POST /newsletter/subscribe" do
    test "subscribes and redirects back", %{conn: conn} do
      Newsletter.set_newsletter_enabled(true)

      conn =
        conn
        |> put_req_header("referer", "http://localhost:4002/")
        |> post(~p"/newsletter/subscribe", %{email: "new@example.com"})

      assert redirected_to(conn) == "/"
      assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "Check your inbox"
    end

    test "handles already confirmed subscriber", %{conn: conn} do
      Newsletter.set_newsletter_enabled(true)

      # Create a confirmed subscriber directly
      now = DateTime.utc_now() |> DateTime.truncate(:second)

      %Subscriber{}
      |> Subscriber.changeset(%{
        email: "confirmed@example.com",
        status: "confirmed",
        confirmed_at: now
      })
      |> Repo.insert!()

      conn =
        conn
        |> put_req_header("referer", "http://localhost:4002/about")
        |> post(~p"/newsletter/subscribe", %{email: "confirmed@example.com"})

      assert redirected_to(conn) == "/about"
      assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "already subscribed"
    end

    test "shows error for invalid email", %{conn: conn} do
      Newsletter.set_newsletter_enabled(true)

      conn =
        conn
        |> put_req_header("referer", "http://localhost:4002/")
        |> post(~p"/newsletter/subscribe", %{email: "not-an-email"})

      assert redirected_to(conn) == "/"
      assert Phoenix.Flash.get(conn.assigns.flash, :error) =~ "valid email"
    end

    test "redirects to / when no referer", %{conn: conn} do
      Newsletter.set_newsletter_enabled(true)

      conn = post(conn, ~p"/newsletter/subscribe", %{email: "test@example.com"})

      assert redirected_to(conn) == "/"
    end
  end

  describe "GET /newsletter/confirm/:token" do
    test "confirms pending subscriber", %{conn: conn} do
      # Create a pending subscriber with a known raw token
      raw_token = "test-confirmation-token-abc123"
      hashed_token = :crypto.hash(:sha256, raw_token) |> Base.encode16(case: :lower)

      %Subscriber{}
      |> Subscriber.changeset(%{
        email: "pending@example.com",
        status: "pending",
        confirmation_token: hashed_token
      })
      |> Repo.insert!()

      conn = get(conn, "/newsletter/confirm/#{raw_token}")

      assert conn.status == 200
      assert conn.resp_body =~ "subscribed"

      # Verify the subscriber is now confirmed
      sub = Repo.get_by!(Subscriber, email: "pending@example.com")
      assert sub.status == "confirmed"
    end

    test "returns error for invalid token", %{conn: conn} do
      conn = get(conn, "/newsletter/confirm/invalid-token-here")

      assert conn.status == 400
      assert conn.resp_body =~ "invalid"
    end
  end
end
