defmodule ToweropsWeb.Org.SettingsLiveTest do
  use ToweropsWeb.ConnCase

  import Phoenix.LiveViewTest
  import Towerops.AccountsFixtures
  import Towerops.AgentsFixtures
  import Towerops.OrganizationsFixtures

  setup do
    user = user_fixture()
    organization = organization_fixture(user.id)

    %{user: user, organization: organization}
  end

  describe "Settings page" do
    test "displays organization settings form", %{conn: conn, user: user, organization: org} do
      {:ok, _view, html} =
        conn
        |> log_in_user(user)
        |> live(~p"/orgs/#{org.slug}/settings")

      assert html =~ "Organization Settings"
      assert html =~ "Organization Name"
      assert html =~ org.name
    end

    test "shows no agents message when no agents exist", %{
      conn: conn,
      user: user,
      organization: org
    } do
      {:ok, _view, html} =
        conn
        |> log_in_user(user)
        |> live(~p"/orgs/#{org.slug}/settings")

      assert html =~ "No agents configured yet"
      assert html =~ "Create an agent"
    end

    test "shows default agent dropdown when agents exist", %{
      conn: conn,
      user: user,
      organization: org
    } do
      {:ok, agent_token, _token} = agent_token_fixture(org.id, "Test Agent")

      {:ok, _view, html} =
        conn
        |> log_in_user(user)
        |> live(~p"/orgs/#{org.slug}/settings")

      assert html =~ "Default Remote Agent"
      assert html =~ agent_token.name
      assert html =~ "No default agent - cloud polling"
    end

    test "updates organization name successfully", %{conn: conn, user: user, organization: org} do
      {:ok, view, _html} =
        conn
        |> log_in_user(user)
        |> live(~p"/orgs/#{org.slug}/settings")

      html =
        view
        |> form("#organization-form", organization: %{name: "Updated Name"})
        |> render_submit()

      assert html =~ "Settings saved successfully"

      # Verify the organization was actually updated
      updated_org = Towerops.Organizations.get_organization!(org.id)
      assert updated_org.name == "Updated Name"
    end

    test "sets default agent for organization", %{conn: conn, user: user, organization: org} do
      {:ok, agent_token, _token} = agent_token_fixture(org.id, "Test Agent")

      {:ok, view, _html} =
        conn
        |> log_in_user(user)
        |> live(~p"/orgs/#{org.slug}/settings")

      html =
        view
        |> form("#organization-form", organization: %{default_agent_token_id: agent_token.id})
        |> render_submit()

      assert html =~ "Settings saved successfully"

      # Verify the default agent was set
      updated_org = Towerops.Organizations.get_organization!(org.id)
      assert updated_org.default_agent_token_id == agent_token.id
    end

    test "clears default agent for organization", %{conn: conn, user: user, organization: org} do
      {:ok, agent_token, _token} = agent_token_fixture(org.id, "Test Agent")

      # First set a default agent
      {:ok, org} =
        Towerops.Organizations.update_organization(org, %{
          default_agent_token_id: agent_token.id
        })

      {:ok, view, _html} =
        conn
        |> log_in_user(user)
        |> live(~p"/orgs/#{org.slug}/settings")

      # Now clear it
      html =
        view
        |> form("#organization-form", organization: %{default_agent_token_id: ""})
        |> render_submit()

      assert html =~ "Settings saved successfully"

      # Verify the default agent was cleared
      updated_org = Towerops.Organizations.get_organization!(org.id)
      assert updated_org.default_agent_token_id == nil
    end

    test "validates organization name", %{conn: conn, user: user, organization: org} do
      {:ok, view, _html} =
        conn
        |> log_in_user(user)
        |> live(~p"/orgs/#{org.slug}/settings")

      # Form requires name field - submitting empty should fail
      html =
        view
        |> form("#organization-form", organization: %{name: ""})
        |> render_submit()

      # The form should still be displayed (not redirected)
      assert html =~ "Organization Name"
    end

    test "requires authentication", %{conn: conn, organization: org} do
      assert {:error, {:redirect, %{to: "/users/log-in"}}} =
               live(conn, ~p"/orgs/#{org.slug}/settings")
    end

    test "validates organization name on change", %{conn: conn, user: user, organization: org} do
      {:ok, view, _html} =
        conn
        |> log_in_user(user)
        |> live(~p"/orgs/#{org.slug}/settings")

      html =
        view
        |> form("#organization-form", organization: %{name: ""})
        |> render_change()

      assert html =~ "Organization Name"
    end

    test "applies SNMP config to all devices", %{conn: conn, user: user, organization: org} do
      {:ok, view, _html} =
        conn
        |> log_in_user(user)
        |> live(~p"/orgs/#{org.slug}/settings")

      html = render_click(view, "apply_snmp_to_all")
      assert html =~ "Applied SNMP configuration to"
    end

    test "applies default agent to all devices", %{conn: conn, user: user, organization: org} do
      {:ok, view, _html} =
        conn
        |> log_in_user(user)
        |> live(~p"/orgs/#{org.slug}/settings")

      html = render_click(view, "apply_agent_to_all")
      assert html =~ "Applied default agent to"
    end

    test "toggles default organization", %{conn: conn, user: user, organization: org} do
      {:ok, view, _html} =
        conn
        |> log_in_user(user)
        |> live(~p"/orgs/#{org.slug}/settings")

      html = render_click(view, "toggle_default_org")

      # Either sets as default or shows already default message
      assert html =~ "default organization" or html =~ "already your default"
    end
  end
end
