defmodule TarakanWeb.BillingLiveTest do
  use TarakanWeb.ConnCase, async: true

  import Phoenix.LiveViewTest

  alias Tarakan.Billing.Subscription
  alias Tarakan.Repo

  defp subscription_fixture(account, overrides) do
    attrs =
      Map.merge(
        %{
          account_id: account.id,
          plan: "enterprise",
          status: "active",
          stripe_customer_id: "cus_lv",
          stripe_subscription_id: "sub_lv_#{account.id}",
          current_period_end: DateTime.utc_now()
        },
        overrides
      )

    %Subscription{}
    |> Subscription.changeset(attrs)
    |> Repo.insert!()
  end

  test "redirects anonymous visitors to login", %{conn: conn} do
    assert {:error, {:redirect, %{to: "/accounts/log-in"}}} = live(conn, ~p"/accounts/billing")
  end

  test "shows the unsubscribed state with the managed-disclosure button", %{conn: conn} do
    {:ok, view, _html} = conn |> log_in_account(account_fixture()) |> live(~p"/accounts/billing")

    assert has_element?(view, "#billing-current")
    assert has_element?(view, "#billing-plan", "None")
    assert has_element?(view, "#billing-subscribe-enterprise")
    refute has_element?(view, "#billing-manage-button")
  end

  test "shows the active plan, status, period end, and manage button", %{conn: conn} do
    account = account_fixture()
    subscription_fixture(account, %{})

    {:ok, view, _html} = conn |> log_in_account(account) |> live(~p"/accounts/billing")

    assert has_element?(view, "#billing-plan", "Managed disclosure")
    assert has_element?(view, "#billing-status", "Active")
    assert has_element?(view, "#billing-manage-button")
    refute has_element?(view, "#billing-subscribe-enterprise")
  end

  test "renders past_due and canceled states", %{conn: conn} do
    past_due = account_fixture()
    subscription_fixture(past_due, %{status: "past_due"})

    {:ok, view, _html} = conn |> log_in_account(past_due) |> live(~p"/accounts/billing")
    assert has_element?(view, "#billing-status", "Past due")

    canceled = account_fixture()
    subscription_fixture(canceled, %{status: "canceled"})

    {:ok, view, _html} = conn |> log_in_account(canceled) |> live(~p"/accounts/billing")
    assert has_element?(view, "#billing-status", "Canceled")
    assert has_element?(view, "#billing-subscribe-enterprise")
  end

  test "subscribe redirects to Stripe checkout", %{conn: conn} do
    {:ok, view, _html} = conn |> log_in_account(account_fixture()) |> live(~p"/accounts/billing")

    assert {:error, {:redirect, %{to: checkout_url}}} =
             view |> element("#billing-subscribe-enterprise") |> render_click()

    assert checkout_url =~ "https://checkout.stripe.com/"
  end

  test "manage redirects to the Stripe billing portal", %{conn: conn} do
    account = account_fixture()
    subscription_fixture(account, %{})

    {:ok, view, _html} = conn |> log_in_account(account) |> live(~p"/accounts/billing")

    assert {:error, {:redirect, %{to: portal_url}}} =
             view |> element("#billing-manage-button") |> render_click()

    assert portal_url =~ "https://billing.stripe.com/"
  end
end
