defmodule BerrypodWeb.Setup.OnboardingTest do
  use BerrypodWeb.ConnCase, async: false

  import Phoenix.LiveViewTest
  import Berrypod.AccountsFixtures

  alias Berrypod.{Products, Settings}

  describe "access rules" do
    test "accessible on fresh install (no admin)", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/setup")
      assert html =~ "Set up your shop"
      assert html =~ "Set up your account"
    end

    test "redirects to /admin when setup is complete", %{conn: conn} do
      user = user_fixture()
      conn = log_in_user(conn, user)

      {:ok, _} =
        Products.create_provider_connection(%{
          name: "Test",
          provider_type: "printify",
          api_key: "test_key"
        })

      {:ok, _} = Settings.put_secret("stripe_api_key", "sk_test_123")

      {:error, redirect} = live(conn, ~p"/setup")
      assert {:live_redirect, %{to: "/admin"}} = redirect
    end

    test "redirects to login when admin exists but not logged in", %{conn: conn} do
      _user = user_fixture()

      {:error, redirect} = live(conn, ~p"/setup")
      assert {:live_redirect, %{to: "/users/log-in"}} = redirect
    end

    test "redirects to / when site is already live", %{conn: conn} do
      user = user_fixture()
      conn = log_in_user(conn, user)

      {:ok, _} =
        Products.create_provider_connection(%{
          name: "Test",
          provider_type: "printify",
          api_key: "test_key"
        })

      {:ok, _} = Settings.put_secret("stripe_api_key", "sk_test_123")
      {:ok, _} = Settings.set_site_live(true)

      {:error, redirect} = live(conn, ~p"/setup")
      assert {:live_redirect, %{to: "/"}} = redirect
    end
  end

  describe "fresh install (no admin)" do
    test "shows only account card (simplified setup)", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/setup")

      assert html =~ "Set up your account"
      # Provider and Stripe cards are hidden until after account creation
      refute html =~ "Connect a print provider"
      refute html =~ "Connect payments"
    end

    test "creating account auto-confirms and redirects to login", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/setup")

      view
      |> form(~s(form[phx-submit="create_account"]),
        account: %{
          shop_name: "Test Shop",
          email: "admin@example.com",
          password: "valid_password_123",
          password_confirmation: "valid_password_123"
        }
      )
      |> render_submit()

      # The LiveView redirects to /setup/login/:token
      {path, _flash} = assert_redirect(view)
      assert path =~ ~r"/setup/login/.+"
    end
  end

  describe "configure (logged in)" do
    setup :register_and_log_in_user

    test "shows guided setup flow", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/setup")

      # Guided flow shows progress bar
      assert html =~ "Setup progress"
      # Shows one of the setup steps or intro
      assert html =~ "Connect" or html =~ "Let's get started"
    end

    test "clicking start shows provider step", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/setup")

      html = render_click(view, "start_setup")

      assert html =~ "Connect a print provider"
      assert html =~ "Printify"
      assert html =~ "Printful"
    end

    test "selecting a provider shows the API key form", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/setup")

      # First go to provider step
      render_click(view, "start_setup")

      html =
        view
        |> form(~s(form[phx-change="select_provider"]), %{provider_select: %{type: "printify"}})
        |> render_change()

      assert html =~ "API token"
      assert html =~ "Printify"
    end

    test "skipping provider step shows stripe step", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/setup")

      # Start and skip provider
      render_click(view, "start_setup")
      html = render_click(view, "skip_step")

      assert html =~ "Secret key"
      assert html =~ "Connect Stripe"
    end
  end

  describe "completion" do
    setup :register_and_log_in_user

    test "redirects to dashboard when all three steps done", %{conn: conn} do
      {:ok, _} =
        Products.create_provider_connection(%{
          name: "Test",
          provider_type: "printify",
          api_key: "test_key"
        })

      {:ok, _} = Settings.put_secret("stripe_api_key", "sk_test_123")

      {:error, redirect} = live(conn, ~p"/setup")
      assert {:live_redirect, %{to: "/admin"}} = redirect
    end
  end
end
