defmodule SimpleshopThemeWeb.Admin.SettingsTest do
  use SimpleshopThemeWeb.ConnCase, async: false

  import Phoenix.LiveViewTest
  import SimpleshopTheme.AccountsFixtures
  import SimpleshopTheme.ProductsFixtures

  alias SimpleshopTheme.Accounts
  alias SimpleshopTheme.Settings

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

  describe "shop status toggle" do
    setup %{conn: conn, user: user} do
      conn = log_in_user(conn, user)
      %{conn: conn}
    end

    test "shows offline status by default", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/admin/settings")

      assert html =~ "Offline"
      assert html =~ "coming soon"
      assert html =~ "Go live"
    end

    test "can go live", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/settings")

      html = render_click(view, "toggle_site_live")

      assert html =~ "Shop is now live"
      assert html =~ "Live"
      assert html =~ "Take offline"
      assert Settings.site_live?()
    end

    test "can take offline after going live", %{conn: conn} do
      {:ok, _} = Settings.set_site_live(true)
      {:ok, view, _html} = live(conn, ~p"/admin/settings")

      html = render_click(view, "toggle_site_live")

      assert html =~ "Shop taken offline"
      assert html =~ "Offline"
      assert html =~ "Go live"
      refute Settings.site_live?()
    end
  end

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

  describe "authenticated - not configured" do
    setup %{conn: conn, user: user} do
      conn = log_in_user(conn, user)
      %{conn: conn}
    end

    test "renders setup form when Stripe is not configured", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/admin/settings")

      assert html =~ "Settings"
      assert html =~ "Not connected"
      assert html =~ "Connect Stripe"
      assert html =~ "Stripe dashboard"
    end

    test "shows error for empty API key", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/settings")

      html =
        view
        |> form(~s(form[phx-submit="connect_stripe"]), %{stripe: %{api_key: ""}})
        |> render_submit()

      assert html =~ "Please enter your Stripe secret key"
    end
  end

  describe "authenticated - connected (localhost)" do
    setup %{conn: conn, user: user} do
      # Pre-configure a Stripe API key
      Settings.put_secret("stripe_api_key", "sk_test_simulated_key_12345")
      conn = log_in_user(conn, user)
      %{conn: conn}
    end

    test "renders dev mode view with CLI instructions", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/admin/settings")

      assert html =~ "Dev mode"
      assert html =~ "sk_test_•••345"
      assert html =~ "stripe listen"
      assert html =~ "Webhook signing secret"
    end

    test "saves manual signing secret", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/settings")

      html =
        view
        |> form(~s(form[phx-submit="save_signing_secret"]), %{
          webhook: %{signing_secret: "whsec_test_manual_456"}
        })
        |> render_submit()

      assert html =~ "Webhook signing secret saved"
      assert html =~ "whsec_te•••456"
    end

    test "shows error for empty signing secret", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/settings")

      html =
        view
        |> form(~s(form[phx-submit="save_signing_secret"]), %{webhook: %{signing_secret: ""}})
        |> render_submit()

      assert html =~ "Please enter a signing secret"
    end

    test "disconnect clears configuration", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/settings")

      html = render_click(view, "disconnect_stripe")

      assert html =~ "Stripe disconnected"
      assert html =~ "Not connected"
      assert html =~ "Connect Stripe"
      refute Settings.has_secret?("stripe_api_key")
    end
  end

  describe "products section" do
    setup %{conn: conn, user: user} do
      conn = log_in_user(conn, user)
      %{conn: conn}
    end

    test "shows connect button when no provider connected", %{conn: conn} do
      {:ok, view, html} = live(conn, ~p"/admin/settings")

      assert html =~ "Products"
      assert html =~ "Not connected"
      assert has_element?(view, ~s(a[href="/admin/providers/new"]), "Connect to Printify")
    end

    test "shows connection info when provider connected", %{conn: conn} do
      conn_record = provider_connection_fixture(%{name: "Test Shop"})
      product_fixture(%{provider_connection: conn_record})

      {:ok, _view, html} = live(conn, ~p"/admin/settings")

      assert html =~ "Connected"
      assert html =~ "Test Shop"
      assert html =~ "Sync products"
    end
  end

  describe "account section" do
    setup %{conn: conn, user: user} do
      conn = log_in_user(conn, user)
      %{conn: conn, user: user}
    end

    test "renders email and password forms", %{conn: conn, user: user} do
      {:ok, view, html} = live(conn, ~p"/admin/settings")

      assert html =~ "Account"
      assert html =~ user.email
      assert has_element?(view, "#email_form")
      assert has_element?(view, "#password_form")
    end

    test "validates email change", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/settings")

      result =
        view
        |> element("#email_form")
        |> render_change(%{"user" => %{"email" => "with spaces"}})

      assert result =~ "must have the @ sign and no spaces"
    end

    test "submits email change", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/settings")

      result =
        view
        |> form("#email_form", %{"user" => %{"email" => unique_user_email()}})
        |> render_submit()

      assert result =~ "A link to confirm your email"
    end

    test "validates password", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/settings")

      result =
        view
        |> element("#password_form")
        |> render_change(%{
          "user" => %{
            "password" => "short",
            "password_confirmation" => "mismatch"
          }
        })

      assert result =~ "should be at least 12 character(s)"
    end

    test "submits valid password change", %{conn: conn, user: user} do
      new_password = valid_user_password()
      {:ok, view, _html} = live(conn, ~p"/admin/settings")

      form =
        form(view, "#password_form", %{
          "user" => %{
            "email" => user.email,
            "password" => new_password,
            "password_confirmation" => new_password
          }
        })

      render_submit(form)
      new_password_conn = follow_trigger_action(form, conn)

      assert redirected_to(new_password_conn) == ~p"/admin/settings"
      assert Accounts.get_user_by_email_and_password(user.email, new_password)
    end
  end

  describe "advanced section" do
    setup %{conn: conn, user: user} do
      conn = log_in_user(conn, user)
      %{conn: conn}
    end

    test "shows links to system tools", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/settings")

      assert has_element?(view, ~s(a[href="/admin/dashboard"]), "System dashboard")
      assert has_element?(view, ~s(a[href="/admin/errors"]), "Error tracker")
    end
  end
end
