defmodule CentralcloudMy.SecurityLive do
  use CentralcloudMyWeb, :live_view

  alias CentralcloudCore.Security

  @refresh_ms 120_000

  def mount(_params, %{"customer_id" => raw_id}, socket) do
    customer_id = parse_customer_id(raw_id)

    if is_nil(customer_id) do
      {:ok, assign(socket, page_title: "Security Center", state: :error, customer_id: nil) |> assign_defaults()}
    else
      {state, data} = load_data(customer_id)

      if connected?(socket) and state == :active do
        Process.send_after(self(), :refresh, @refresh_ms)
      end

      {:ok,
       socket
       |> assign(page_title: "Security Center", customer_id: customer_id, state: state)
       |> assign(data)}
    end
  end

  def mount(_params, _session, socket) do
    {:ok, assign(socket, page_title: "Security Center", state: :error, customer_id: nil) |> assign_defaults()}
  end

  def handle_info(:refresh, socket) do
    Process.send_after(self(), :refresh, @refresh_ms)
    {state, data} = load_data(socket.assigns.customer_id)
    {:noreply, assign(socket, Map.put(data, :state, state))}
  end

  def handle_event("refresh", _params, %{assigns: %{customer_id: nil}} = socket),
    do: {:noreply, socket}

  def handle_event("refresh", _params, socket) do
    {state, data} = load_data(socket.assigns.customer_id)
    {:noreply, assign(socket, Map.put(data, :state, state))}
  end

  # ---------------------------------------------------------------------------
  # Render
  # ---------------------------------------------------------------------------

  def render(assigns) do
    ~H"""
    <div class="mb-6 flex items-start justify-between gap-4">
      <div>
        <h1 class="text-xl font-bold text-slate-100 flex items-center gap-2">
          🛡️ Security Center
        </h1>
        <p class="text-slate-400 text-sm mt-1">
          Endpoint security monitoring for your infrastructure
        </p>
      </div>
      <div :if={@state == :active} class="text-slate-500 text-xs flex items-center gap-2 mt-2">
        Updated {Calendar.strftime(@last_updated, "%H:%M UTC")}
        <button
          phx-click="refresh"
          class="text-sky-400 hover:text-sky-300 transition-colors text-base leading-none"
        >
          ↻
        </button>
      </div>
    </div>

    <!-- Session / auth error -->
    <div :if={@state == :error} class="bg-slate-800 border border-slate-700 rounded-xl p-8 text-center">
      <div class="text-3xl mb-3">⚠️</div>
      <p class="text-slate-300 font-medium">Could not load your account information.</p>
      <p class="text-slate-500 text-sm mt-1">Please refresh the page or contact support.</p>
    </div>

    <!-- HostBill temporarily unavailable — neutral state, no upsell -->
    <div
      :if={@state == :service_unavailable}
      class="bg-slate-800 border border-slate-700 rounded-xl p-8 text-center"
    >
      <div class="text-3xl mb-3">⚙️</div>
      <p class="text-slate-300 font-medium">Security status temporarily unavailable</p>
      <p class="text-slate-500 text-sm mt-1">Please try again in a moment.</p>
    </div>

    <!-- Security platform unreachable -->
    <div
      :if={@state == :load_error}
      class="bg-slate-800 border border-amber-900/50 rounded-xl p-8 text-center"
    >
      <div class="text-3xl mb-3">📡</div>
      <p class="text-amber-300 font-medium">Could not reach the security monitoring system</p>
      <p class="text-slate-500 text-sm mt-1">Please try again or contact support if this persists.</p>
    </div>

    <!-- No security service — upsell -->
    <div
      :if={@state == :no_service}
      class="bg-slate-800/50 border border-slate-700 rounded-xl p-10 text-center"
    >
      <div class="text-5xl mb-4">🛡️</div>
      <h2 class="text-lg font-semibold text-slate-200 mb-2">Security Monitoring not enabled</h2>
      <p class="text-slate-400 text-sm mb-6 max-w-sm mx-auto leading-relaxed">
        Add endpoint security monitoring to your account for real-time threat detection,
        vulnerability scanning, and compliance insights across your infrastructure.
      </p>
      <a
        href="/support"
        class="inline-flex items-center gap-2 px-5 py-2.5 bg-sky-600 hover:bg-sky-500
               text-white rounded-lg text-sm font-medium transition-colors"
      >
        Contact us to enable →
      </a>
    </div>

    <!-- Active Security Dashboard -->
    <div :if={@state == :active}>
      <!-- Summary stats row -->
      <div class="grid grid-cols-2 sm:grid-cols-4 gap-4 mb-6">
        <div class="bg-slate-800 border border-slate-700 rounded-lg p-4">
          <p class="text-slate-500 text-[11px] font-semibold uppercase tracking-wider mb-2">
            Monitored Endpoints
          </p>
          <p class="text-3xl font-bold text-sky-400">{length(@agents)}</p>
          <p class="text-slate-500 text-xs mt-1">{@online_count} online</p>
        </div>

        <div class={[
          "bg-slate-800 border rounded-lg p-4",
          if(@total_critical > 0, do: "border-red-800", else: "border-slate-700")
        ]}>
          <p class="text-slate-500 text-[11px] font-semibold uppercase tracking-wider mb-2">
            Critical CVEs
          </p>
          <p class={[
            "text-3xl font-bold",
            if(@total_critical > 0, do: "text-red-400", else: "text-slate-400")
          ]}>
            {@total_critical}
          </p>
        </div>

        <div class={[
          "bg-slate-800 border rounded-lg p-4",
          if(@total_high > 0, do: "border-orange-800", else: "border-slate-700")
        ]}>
          <p class="text-slate-500 text-[11px] font-semibold uppercase tracking-wider mb-2">
            High CVEs
          </p>
          <p class={[
            "text-3xl font-bold",
            if(@total_high > 0, do: "text-orange-400", else: "text-slate-400")
          ]}>
            {@total_high}
          </p>
        </div>

        <div class="bg-slate-800 border border-slate-700 rounded-lg p-4">
          <p class="text-slate-500 text-[11px] font-semibold uppercase tracking-wider mb-2">
            Risk Level
          </p>
          <p class={["font-bold text-base mt-2", risk_color(@total_critical, @total_high)]}>
            {risk_label(@total_critical, @total_high)}
          </p>
        </div>
      </div>

      <!-- No agents found -->
      <div
        :if={@agents == []}
        class="bg-slate-800 border border-slate-700 rounded-lg p-8 text-center text-slate-400"
      >
        <div class="text-3xl mb-2">📡</div>
        <p class="font-medium">No monitored endpoints found</p>
        <p class="text-sm mt-1">Contact support to add your systems.</p>
      </div>

      <!-- Agents table -->
      <div :if={@agents != []} class="bg-slate-800 border border-slate-700 rounded-lg overflow-hidden">
        <div class="px-5 py-3.5 border-b border-slate-700">
          <h2 class="font-semibold text-slate-200 text-sm">Monitored Endpoints</h2>
        </div>
        <div class="overflow-x-auto">
          <table class="w-full text-sm">
            <thead>
              <tr class="text-left border-b border-slate-700/50">
                <th class="px-5 py-3 text-slate-500 text-xs font-semibold uppercase tracking-wider">
                  Endpoint
                </th>
                <th class="px-5 py-3 text-slate-500 text-xs font-semibold uppercase tracking-wider">
                  OS
                </th>
                <th class="px-5 py-3 text-slate-500 text-xs font-semibold uppercase tracking-wider">
                  Status
                </th>
                <th class="px-5 py-3 text-slate-500 text-xs font-semibold uppercase tracking-wider">
                  Critical
                </th>
                <th class="px-5 py-3 text-slate-500 text-xs font-semibold uppercase tracking-wider">
                  High
                </th>
                <th class="px-5 py-3 text-slate-500 text-xs font-semibold uppercase tracking-wider">
                  Medium
                </th>
                <th class="px-5 py-3 text-slate-500 text-xs font-semibold uppercase tracking-wider">
                  Last Seen
                </th>
              </tr>
            </thead>
            <tbody>
              <tr
                :for={agent <- @agents}
                class="border-t border-slate-700/30 hover:bg-slate-700/20 transition-colors"
              >
                <td class="px-5 py-3.5">
                  <div class="font-medium text-slate-200">{agent["name"]}</div>
                  <div class="text-slate-500 text-xs font-mono mt-0.5">{agent["ip"]}</div>
                </td>
                <td class="px-5 py-3.5 text-slate-400 text-xs">
                  {get_in(agent, ["os", "name"]) || "—"}
                </td>
                <td class="px-5 py-3.5">
                  <span class={agent_status_badge(agent["status"])}>
                    {agent["status"] || "unknown"}
                  </span>
                </td>
                <td class="px-5 py-3.5">
                  <span class={vuln_class(agent.vuln_counts["critical"] || 0, :red)}>
                    {agent.vuln_counts["critical"] || 0}
                  </span>
                </td>
                <td class="px-5 py-3.5">
                  <span class={vuln_class(agent.vuln_counts["high"] || 0, :orange)}>
                    {agent.vuln_counts["high"] || 0}
                  </span>
                </td>
                <td class="px-5 py-3.5">
                  <span class={vuln_class(agent.vuln_counts["medium"] || 0, :yellow)}>
                    {agent.vuln_counts["medium"] || 0}
                  </span>
                </td>
                <td class="px-5 py-3.5 text-slate-400 text-xs">
                  {format_time(agent["lastKeepAlive"])}
                </td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>

      <p class="mt-4 text-slate-600 text-xs">
        Contact support for detailed reports or guided remediation.
      </p>
    </div>
    """
  end

  # ---------------------------------------------------------------------------
  # Private helpers
  # ---------------------------------------------------------------------------

  defp load_data(customer_id) do
    case Security.customer_has_security_service?(customer_id) do
      :unavailable ->
        {:service_unavailable, default_assigns()}

      false ->
        {:no_service, default_assigns()}

      true ->
        case Security.get_monitored_agents(customer_id) do
          {:ok, agents} ->
            enriched =
              Enum.map(agents, fn agent ->
                counts =
                  case Security.get_agent_vulnerability_counts(agent["id"]) do
                    {:ok, c} -> c
                    _ -> %{}
                  end

                Map.put(agent, :vuln_counts, counts)
              end)

            total_critical = Enum.sum(Enum.map(enriched, &(&1.vuln_counts["critical"] || 0)))
            total_high = Enum.sum(Enum.map(enriched, &(&1.vuln_counts["high"] || 0)))
            online_count = Enum.count(enriched, &(&1["status"] == "active"))

            {:active,
             %{
               agents: enriched,
               total_critical: total_critical,
               total_high: total_high,
               online_count: online_count,
               last_updated: DateTime.utc_now()
             }}

          {:error, _} ->
            {:load_error, default_assigns()}
        end
    end
  end

  defp default_assigns do
    %{agents: [], total_critical: 0, total_high: 0, online_count: 0, last_updated: DateTime.utc_now()}
  end

  defp assign_defaults(socket) do
    assign(socket, agents: [], total_critical: 0, total_high: 0, online_count: 0, last_updated: DateTime.utc_now())
  end

  defp parse_customer_id(id) when is_integer(id), do: id

  defp parse_customer_id(id) when is_binary(id) do
    case Integer.parse(id) do
      {n, ""} -> n
      _ -> nil
    end
  end

  defp parse_customer_id(_), do: nil

  defp agent_status_badge("active"),
    do: "inline-block px-2 py-0.5 rounded text-[11px] font-semibold bg-green-900/60 text-green-300 border border-green-700/50"

  defp agent_status_badge("disconnected"),
    do: "inline-block px-2 py-0.5 rounded text-[11px] font-semibold bg-red-900/60 text-red-300 border border-red-700/50"

  defp agent_status_badge(_),
    do: "inline-block px-2 py-0.5 rounded text-[11px] font-semibold bg-slate-700 text-slate-400 border border-slate-600"

  defp vuln_class(0, _), do: "text-slate-500 font-medium"
  defp vuln_class(_, :red), do: "text-red-400 font-bold"
  defp vuln_class(_, :orange), do: "text-orange-400 font-bold"
  defp vuln_class(_, :yellow), do: "text-yellow-400 font-bold"
  defp vuln_class(_, _), do: "text-slate-300 font-medium"

  defp risk_color(crit, _) when crit > 0, do: "text-red-400"
  defp risk_color(_, high) when high > 5, do: "text-orange-400"
  defp risk_color(_, high) when high > 0, do: "text-yellow-400"
  defp risk_color(_, _), do: "text-green-400"

  defp risk_label(crit, _) when crit > 0, do: "⚠️ Critical"
  defp risk_label(_, high) when high > 5, do: "🔶 High"
  defp risk_label(_, high) when high > 0, do: "🔸 Elevated"
  defp risk_label(_, _), do: "✅ Low"

  defp format_time(nil), do: "—"

  defp format_time(iso) do
    case DateTime.from_iso8601(iso) do
      {:ok, dt, _} -> Calendar.strftime(dt, "%d %b %H:%M")
      _ -> iso
    end
  end
end
