defmodule ToweropsWeb.SiteLiveTest do
  use ToweropsWeb.ConnCase

  import Phoenix.LiveViewTest

  setup :register_and_log_in_user

  setup %{user: user} do
    {:ok, organization} = Towerops.Organizations.create_organization(%{name: "Test Org"}, user.id)
    %{organization: organization}
  end

  describe "Index" do
    test "lists all sites", %{conn: conn, organization: organization} do
      {:ok, site} =
        Towerops.Sites.create_site(%{
          name: "Test Site",
          location: "Building A",
          organization_id: organization.id
        })

      {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/sites")

      assert html =~ "Sites"
      assert html =~ site.name
      assert html =~ "Building A"
    end

    test "displays empty state when no sites", %{conn: conn, organization: organization} do
      {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/sites")

      assert html =~ "No sites"
    end

    test "has link to create new site", %{conn: conn, organization: organization} do
      {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/sites")

      assert html =~ "New Site"
    end

    test "requires authentication", %{organization: organization} do
      conn = build_conn()
      {:error, redirect} = live(conn, ~p"/orgs/#{organization.slug}/sites")

      assert {:redirect, %{to: path}} = redirect
      assert path == ~p"/users/log-in"
    end
  end

  describe "Show" do
    setup %{organization: organization} do
      {:ok, site} =
        Towerops.Sites.create_site(%{
          name: "Test Site",
          location: "Building A",
          description: "Main site",
          organization_id: organization.id
        })

      %{site: site}
    end

    test "displays site details", %{conn: conn, organization: organization, site: site} do
      {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/sites/#{site.id}")

      assert html =~ site.name
      assert html =~ "Building A"
      assert html =~ "Main site"
    end

    test "displays equipment at site", %{conn: conn, organization: organization, site: site} do
      {:ok, device} =
        Towerops.Devices.create_device(%{
          name: "Router 1",
          ip_address: "192.168.1.1",
          site_id: site.id
        })

      {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/sites/#{site.id}")

      assert html =~ device.name
      assert html =~ "192.168.1.1"
    end

    test "displays empty state when no equipment", %{
      conn: conn,
      organization: organization,
      site: site
    } do
      {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/sites/#{site.id}")

      assert html =~ "Add your first device"
    end

    test "displays parent site link", %{conn: conn, organization: organization, site: site} do
      {:ok, parent_site} =
        Towerops.Sites.create_site(%{
          name: "Parent Site",
          organization_id: organization.id
        })

      {:ok, updated_site} =
        Towerops.Sites.update_site(site, %{parent_site_id: parent_site.id})

      {:ok, _view, html} =
        live(conn, ~p"/orgs/#{organization.slug}/sites/#{updated_site.id}")

      assert html =~ "Parent Site"
      assert html =~ parent_site.name
    end

    test "displays child sites", %{conn: conn, organization: organization, site: site} do
      {:ok, child_site} =
        Towerops.Sites.create_site(%{
          name: "Child Site",
          parent_site_id: site.id,
          organization_id: organization.id
        })

      {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/sites/#{site.id}")

      assert html =~ "Child Sites"
      assert html =~ child_site.name
    end

    test "deletes site", %{conn: conn, organization: organization, site: site} do
      {:ok, view, _html} = live(conn, ~p"/orgs/#{organization.slug}/sites/#{site.id}/edit")

      {:ok, _, html} =
        view
        |> element("button", "Delete Site")
        |> render_click()
        |> follow_redirect(conn, ~p"/orgs/#{organization.slug}/sites")

      assert html =~ "Site deleted successfully"
    end

    test "requires authentication", %{organization: organization, site: site} do
      conn = build_conn()
      {:error, redirect} = live(conn, ~p"/orgs/#{organization.slug}/sites/#{site.id}")

      assert {:redirect, %{to: path}} = redirect
      assert path == ~p"/users/log-in"
    end
  end

  describe "New" do
    test "renders new site form", %{conn: conn, organization: organization} do
      {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/sites/new")

      assert html =~ "New Site"
      assert html =~ "Add a new site to your organization"
    end

    test "creates new site", %{conn: conn, organization: organization} do
      {:ok, view, _html} = live(conn, ~p"/orgs/#{organization.slug}/sites/new")

      result =
        view
        |> form("#site-form",
          site: %{
            name: "New Site",
            location: "Building B",
            description: "New location"
          }
        )
        |> render_submit()

      # Should redirect to the newly created site's show page
      assert {:error, {:live_redirect, %{to: redirect_path}}} = result
      assert redirect_path =~ "/orgs/#{organization.slug}/sites/"
    end

    test "validates required fields", %{conn: conn, organization: organization} do
      {:ok, view, _html} = live(conn, ~p"/orgs/#{organization.slug}/sites/new")

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

      assert html =~ "can&#39;t be blank"
    end

    test "requires authentication", %{organization: organization} do
      conn = build_conn()
      {:error, redirect} = live(conn, ~p"/orgs/#{organization.slug}/sites/new")

      assert {:redirect, %{to: path}} = redirect
      assert path == ~p"/users/log-in"
    end
  end

  describe "Edit" do
    setup %{organization: organization} do
      {:ok, site} =
        Towerops.Sites.create_site(%{
          name: "Test Site",
          organization_id: organization.id
        })

      %{site: site}
    end

    test "renders edit form", %{conn: conn, organization: organization, site: site} do
      {:ok, _view, html} = live(conn, ~p"/orgs/#{organization.slug}/sites/#{site.id}/edit")

      assert html =~ "Edit Site"
      assert html =~ "Update site details"
    end

    test "updates site", %{conn: conn, organization: organization, site: site} do
      {:ok, view, _html} = live(conn, ~p"/orgs/#{organization.slug}/sites/#{site.id}/edit")

      {:ok, _, html} =
        view
        |> form("#site-form",
          site: %{
            name: "Updated Site",
            location: "New Location"
          }
        )
        |> render_submit()
        |> follow_redirect(conn, ~p"/orgs/#{organization.slug}/sites")

      assert html =~ "Site updated successfully"
      assert html =~ "Updated Site"
    end

    test "requires authentication", %{organization: organization, site: site} do
      conn = build_conn()
      {:error, redirect} = live(conn, ~p"/orgs/#{organization.slug}/sites/#{site.id}/edit")

      assert {:redirect, %{to: path}} = redirect
      assert path == ~p"/users/log-in"
    end
  end
end
