defmodule Berrypod.Newsletter.NotifierTest do
  use Berrypod.DataCase, async: true

  import Swoosh.TestAssertions
  import Berrypod.NewsletterFixtures

  alias Berrypod.Newsletter.Notifier

  describe "deliver_confirmation/2" do
    test "sends multipart email with confirmation link" do
      sub = confirmed_subscriber_fixture(email: "confirm@example.com")
      token = "test-token-123"

      assert {:ok, _} = Notifier.deliver_confirmation(sub, token)

      assert_email_sent(fn email ->
        assert email.to == [{"", "confirm@example.com"}]
        assert email.subject == "Confirm your subscription"

        # text fallback
        assert email.text_body =~ "confirm@example.com" || email.text_body =~ token
        assert email.text_body =~ "/newsletter/confirm/test-token-123"

        # html version
        assert email.html_body =~ "Confirm subscription"
        assert email.html_body =~ "/newsletter/confirm/test-token-123"
        assert email.html_body =~ "<!DOCTYPE html>"
      end)
    end
  end

  describe "deliver_campaign/2" do
    test "sends multipart email with HTML wrapper" do
      sub = confirmed_subscriber_fixture(email: "reader@example.com")
      campaign = campaign_fixture(subject: "Big news", body: "Hello world!\n\nSecond paragraph.")

      assert {:ok, _} = Notifier.deliver_campaign(campaign, sub)

      assert_email_sent(fn email ->
        assert email.to == [{"", "reader@example.com"}]
        assert email.subject == "Big news"

        # text fallback has body and unsubscribe
        assert email.text_body =~ "Hello world!"
        assert email.text_body =~ "Unsubscribe:"

        # html version wraps in template
        assert email.html_body =~ "<!DOCTYPE html>"
        assert email.html_body =~ "<p>Hello world!</p>"
        assert email.html_body =~ "<p>Second paragraph.</p>"
        assert email.html_body =~ "Unsubscribe"
      end)
    end

    test "replaces {{unsubscribe_url}} in both text and html" do
      sub = confirmed_subscriber_fixture(email: "unsub@example.com")

      campaign =
        campaign_fixture(body: "Click here to unsubscribe: {{unsubscribe_url}}")

      assert {:ok, _} = Notifier.deliver_campaign(campaign, sub)

      assert_email_sent(fn email ->
        refute email.text_body =~ "{{unsubscribe_url}}"
        refute email.html_body =~ "{{unsubscribe_url}}"
        assert email.text_body =~ "/unsubscribe/"
        assert email.html_body =~ "/unsubscribe/"
      end)
    end

    test "includes List-Unsubscribe headers" do
      sub = confirmed_subscriber_fixture()
      campaign = campaign_fixture()

      assert {:ok, _} = Notifier.deliver_campaign(campaign, sub)

      assert_email_sent(fn email ->
        headers = Map.new(email.headers)
        assert headers["List-Unsubscribe"] =~ "/unsubscribe/"
        assert headers["List-Unsubscribe-Post"] == "List-Unsubscribe=One-Click"
      end)
    end
  end

  describe "deliver_test/2" do
    test "sends test email with [Test] prefix in subject" do
      campaign =
        campaign_fixture(subject: "Big launch", body: "Preview this!\n\n{{unsubscribe_url}}")

      assert {:ok, _} = Notifier.deliver_test(campaign, "admin@example.com")

      assert_email_sent(fn email ->
        assert email.to == [{"", "admin@example.com"}]
        assert email.subject == "[Test] Big launch"
        assert email.text_body =~ "Preview this!"
        assert email.html_body =~ "<!DOCTYPE html>"
      end)
    end
  end

  describe "text_to_html/1" do
    test "wraps paragraphs split by blank lines" do
      html = Notifier.text_to_html("First paragraph.\n\nSecond paragraph.")
      assert html =~ "<p>First paragraph.</p>"
      assert html =~ "<p>Second paragraph.</p>"
    end

    test "preserves single line breaks within paragraphs" do
      html = Notifier.text_to_html("Line one.\nLine two.")
      assert html =~ "Line one.<br>Line two."
    end

    test "escapes HTML in content" do
      html = Notifier.text_to_html("Use <b>bold</b> & \"quotes\"")
      assert html =~ "&lt;b&gt;bold&lt;/b&gt;"
      assert html =~ "&amp;"
      assert html =~ "&quot;quotes&quot;"
    end

    test "turns URLs into links" do
      html = Notifier.text_to_html("Visit https://example.com/shop for more")
      assert html =~ ~s(<a href="https://example.com/shop")
      assert html =~ "https://example.com/shop</a>"
    end
  end

  describe "wrap_html/2" do
    test "includes shop name in header" do
      html = Notifier.wrap_html("Test Shop", "<p>Hello</p>")
      assert html =~ "Test Shop"
      assert html =~ "<!DOCTYPE html>"
      assert html =~ "<p>Hello</p>"
    end

    test "includes unsubscribe link when provided" do
      html = Notifier.wrap_html("Shop", "<p>Hi</p>", "https://example.com/unsub")
      assert html =~ "https://example.com/unsub"
      assert html =~ "Unsubscribe"
    end

    test "omits footer when no unsubscribe url" do
      html = Notifier.wrap_html("Shop", "<p>Hi</p>")
      refute html =~ "Unsubscribe"
    end

    test "escapes shop name in HTML" do
      html = Notifier.wrap_html("Bob's <Shop>", "<p>Hi</p>")
      assert html =~ "&lt;Shop&gt;"
      refute html =~ "<Shop>"
    end
  end
end
