defmodule ToweropsWeb.UserSettingsLiveTest do
  use ToweropsWeb.ConnCase, async: true

  import Phoenix.LiveViewTest
  import Towerops.AccountsFixtures

  alias Towerops.Accounts

  describe "UserSettingsLive with sudo mode" do
    setup :register_and_log_in_user_with_sudo

    test "renders settings page", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/users/settings")

      assert html =~ "Account Settings"
      assert html =~ "Personal Information"
    end

    test "allows updating profile", %{conn: conn, user: user} do
      {:ok, view, _html} = live(conn, ~p"/users/settings?tab=personal")

      # Update profile
      result =
        view
        |> form("#update_profile", user: %{first_name: "John", last_name: "Doe"})
        |> render_submit()

      assert result =~ "Profile updated successfully"

      # Verify database was updated
      updated_user = Accounts.get_user!(user.id)
      assert updated_user.first_name == "John"
      assert updated_user.last_name == "Doe"
    end

    test "allows updating email", %{conn: conn, user: user} do
      new_email = unique_user_email()
      {:ok, view, _html} = live(conn, ~p"/users/settings?tab=account")

      # Update email
      result =
        view
        |> form("#update_email", user: %{email: new_email})
        |> render_submit()

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

      # Old email should still be in use
      assert Accounts.get_user_by_email(user.email)
    end

    test "allows updating password", %{conn: conn} do
      new_password = valid_user_password()
      {:ok, view, _html} = live(conn, ~p"/users/settings?tab=account")

      # Update password - this will log the user out
      assert {:error, {:redirect, %{to: "/users/log-in"}}} =
               view
               |> form("#update_password",
                 user: %{
                   password: new_password,
                   password_confirmation: new_password
                 }
               )
               |> render_submit()
    end

    test "shows error for mismatched password confirmation", %{conn: conn} do
      new_password = valid_user_password()
      {:ok, view, _html} = live(conn, ~p"/users/settings?tab=account")

      # Try to update password with non-matching confirmation - page stays on form
      html =
        view
        |> form("#update_password",
          user: %{
            password: new_password,
            password_confirmation: "different_password"
          }
        )
        |> render_submit()

      # Should still be on the settings page with the form visible
      assert html =~ "Account Settings"
      assert html =~ "Change Password"
    end

    test "shows tabs navigation", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/users/settings")

      # Check for tab navigation
      assert html =~ "Personal"
      assert html =~ "Account"
      assert html =~ "Security"
      assert html =~ "API"
      assert html =~ "Sessions"
      assert html =~ "Notifications"
    end

    test "allows switching tabs via params", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/users/settings?tab=security")

      assert html =~ "Account Settings"
      # Security tab should be active (would need to check for active class in real template)
    end
  end

  describe "UserSettingsLive TOTP management with sudo mode" do
    setup :register_and_log_in_user_with_sudo

    test "shows enrolled TOTP devices", %{conn: conn, user: user} do
      # Create a TOTP device
      Accounts.create_totp_device(user.id, "Test Authenticator")

      {:ok, _view, html} = live(conn, ~p"/users/settings?tab=security")

      assert html =~ "Test Authenticator"
    end

    test "shows multiple TOTP devices", %{conn: conn, user: user} do
      # Create two TOTP devices
      {:ok, _device1, _secret1} = Accounts.create_totp_device(user.id, "Device 1")
      {:ok, _device2, _secret2} = Accounts.create_totp_device(user.id, "Device 2")

      {:ok, _view, html} = live(conn, ~p"/users/settings?tab=security")

      # Verify both devices are shown
      assert html =~ "Device 1"
      assert html =~ "Device 2"
    end
  end

  describe "UserSettingsLive sessions with sudo mode" do
    setup :register_and_log_in_user_with_sudo

    test "shows active sessions", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/users/settings?tab=sessions")

      assert html =~ "Active Sessions"
      assert html =~ "Login History"
    end

    test "opens and cancels revoke all modal", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/users/settings?tab=sessions")

      html = render_click(view, "show_revoke_all_modal")
      assert html =~ "Revoke All"

      html = render_click(view, "cancel_revoke_all")
      refute html =~ "Are you sure"
    end

    test "shows mobile devices section on notifications tab", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/users/settings?tab=notifications")

      assert html =~ "Mobile Devices"
    end
  end

  describe "UserSettingsLive API tokens with sudo mode" do
    setup :register_and_log_in_user_with_sudo

    test "shows API tokens tab", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/users/settings?tab=api")

      assert html =~ "API Tokens"
    end

    test "opens add token modal", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/users/settings?tab=api")

      html = render_click(view, "show_add_token_modal")

      assert html =~ "Create API Token"
    end

    test "cancels add token modal", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/users/settings?tab=api")

      render_click(view, "show_add_token_modal")
      html = render_click(view, "cancel_add_token")

      refute html =~ "Create API Token"
    end
  end

  describe "UserSettingsLive login history with sudo mode" do
    setup :register_and_log_in_user_with_sudo

    test "shows login history", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/users/settings?tab=sessions")

      assert html =~ "Login History"
    end

    test "paginates login history", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/users/settings?tab=sessions&page=1")

      assert html =~ "Login History"
    end
  end

  describe "UserSettingsLive API token creation with sudo mode" do
    setup :register_and_log_in_user_with_sudo

    test "creates API token and shows it", %{conn: conn, user: user} do
      {:ok, org} = Towerops.Organizations.create_organization(%{name: "Token Org"}, user.id)

      {:ok, view, _html} = live(conn, ~p"/users/settings?tab=api")

      render_click(view, "show_add_token_modal")

      html =
        render_click(view, "create_api_token", %{
          "token" => %{"name" => "My Token", "organization_id" => org.id}
        })

      assert html =~ "My Token" or html =~ "API Tokens"
    end

    test "create_api_token without name shows error", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/users/settings?tab=api")

      html = render_click(view, "create_api_token", %{})
      assert html =~ "required" or html =~ "API Tokens"
    end

    test "close_token_modal clears token", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/users/settings?tab=api")

      html = render_click(view, "close_token_modal")
      assert html =~ "API Tokens"
    end
  end

  describe "UserSettingsLive session management with sudo mode" do
    setup :register_and_log_in_user_with_sudo

    test "shows notification tab with add device modal", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/users/settings?tab=notifications")

      html = render_click(view, "show_add_device_modal")
      assert html =~ "Mobile" or html =~ "Device"

      html = render_click(view, "cancel_add_device")
      assert html =~ "Mobile Devices"
    end
  end

  describe "UserSettingsLive password breach check with sudo mode" do
    setup :register_and_log_in_user_with_sudo

    test "check_password_breach with empty value", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/users/settings?tab=account")

      html = render_click(view, "check_password_breach", %{"value" => ""})
      assert html =~ "Account Settings"
    end

    test "check_password_breach with no value param", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/users/settings?tab=account")

      html = render_click(view, "check_password_breach", %{})
      assert html =~ "Account Settings"
    end
  end
end
