defmodule ToweropsWeb.CheckLive.FormComponent do
  @moduledoc false
  use ToweropsWeb, :live_component

  alias Towerops.Monitoring

  @impl true
  def render(assigns) do
    ~H"""
    <div class="relative z-50">
      <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity"></div>

      <div class="fixed inset-0 z-10 overflow-y-auto">
        <div class="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
          <div class="relative transform overflow-hidden rounded-lg bg-white dark:bg-gray-800 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg">
            <.form
              for={@form}
              id="check-form"
              phx-target={@myself}
              phx-change="validate"
              phx-submit="save"
            >
              <div class="bg-white dark:bg-gray-800 px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
                <div class="flex items-start justify-between mb-4">
                  <h3 class="text-lg font-semibold text-gray-900 dark:text-white">
                    Add Service Check
                  </h3>
                  <button
                    type="button"
                    phx-click="close"
                    phx-target={@myself}
                    class="text-gray-400 hover:text-gray-500 dark:hover:text-gray-300"
                  >
                    <.icon name="hero-x-mark" class="h-6 w-6" />
                  </button>
                </div>

                <div class="space-y-4">
                  <!-- Check Type Selection -->
                  <div>
                    <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                      Check Type
                    </label>
                    <.input
                      field={@form[:check_type]}
                      type="select"
                      options={[
                        {"HTTP/HTTPS Check", "http"},
                        {"TCP Port Check", "tcp"},
                        {"DNS Check", "dns"}
                      ]}
                      phx-change="change_type"
                      phx-target={@myself}
                    />
                  </div>
                  
    <!-- Check Name -->
                  <div>
                    <.input
                      field={@form[:name]}
                      type="text"
                      label="Check Name"
                      placeholder="e.g., Web Server Check"
                    />
                  </div>
                  
    <!-- Dynamic fields based on check type -->
                  <%= case @selected_type do %>
                    <% "http" -> %>
                      {render_http_fields(assigns)}
                    <% "tcp" -> %>
                      {render_tcp_fields(assigns)}
                    <% "dns" -> %>
                      {render_dns_fields(assigns)}
                    <% _ -> %>
                      <div class="text-sm text-gray-500 dark:text-gray-400">
                        Select a check type to configure
                      </div>
                  <% end %>
                  
    <!-- Common Settings -->
                  <div class="grid grid-cols-2 gap-4">
                    <div>
                      <.input
                        field={@form[:interval_seconds]}
                        type="number"
                        label="Interval (seconds)"
                      />
                    </div>
                    <div>
                      <.input field={@form[:timeout_ms]} type="number" label="Timeout (ms)" />
                    </div>
                  </div>
                </div>
              </div>

              <div class="bg-gray-50 dark:bg-gray-900/50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6 gap-2">
                <.button type="submit" phx-disable-with="Creating...">
                  Create Check
                </.button>
                <.button
                  type="button"
                  phx-click="close"
                  phx-target={@myself}
                  class="bg-white dark:bg-gray-700"
                >
                  Cancel
                </.button>
              </div>
            </.form>
          </div>
        </div>
      </div>
    </div>
    """
  end

  defp render_http_fields(assigns) do
    ~H"""
    <div class="space-y-4">
      <div>
        <.input field={@form[:url]} type="text" label="URL" placeholder="https://example.com/health" />
      </div>

      <div class="grid grid-cols-2 gap-4">
        <div>
          <.input
            field={@form[:method]}
            type="select"
            label="Method"
            options={["GET", "POST", "PUT", "DELETE", "HEAD"]}
          />
        </div>
        <div>
          <.input
            field={@form[:expected_status]}
            type="number"
            label="Expected Status"
            placeholder="200"
          />
        </div>
      </div>

      <div class="flex items-center gap-4">
        <label class="flex items-center gap-2">
          <.input field={@form[:verify_ssl]} type="checkbox" />
          <span class="text-sm text-gray-700 dark:text-gray-300">Verify SSL Certificate</span>
        </label>

        <label class="flex items-center gap-2">
          <.input field={@form[:follow_redirects]} type="checkbox" />
          <span class="text-sm text-gray-700 dark:text-gray-300">Follow Redirects</span>
        </label>
      </div>

      <details class="border border-gray-200 dark:border-gray-700 rounded-lg p-3">
        <summary class="cursor-pointer text-sm font-medium text-gray-700 dark:text-gray-300">
          Advanced Options
        </summary>
        <div class="mt-3 space-y-3">
          <div>
            <.input
              field={@form[:content_match]}
              type="text"
              label="Content Match (regex)"
              placeholder="Optional regex pattern"
            />
          </div>
        </div>
      </details>
    </div>
    """
  end

  defp render_tcp_fields(assigns) do
    ~H"""
    <div class="space-y-4">
      <div class="grid grid-cols-2 gap-4">
        <div>
          <.input field={@form[:host]} type="text" label="Host" placeholder="example.com" />
        </div>
        <div>
          <.input field={@form[:port]} type="number" label="Port" placeholder="80" />
        </div>
      </div>

      <div>
        <.input
          field={@form[:send_string]}
          type="text"
          label="Send String (optional)"
          placeholder="Text to send after connecting"
        />
      </div>

      <div>
        <.input
          field={@form[:expect_string]}
          type="text"
          label="Expect String (optional)"
          placeholder="Expected response pattern"
        />
      </div>
    </div>
    """
  end

  defp render_dns_fields(assigns) do
    ~H"""
    <div class="space-y-4">
      <div>
        <.input field={@form[:hostname]} type="text" label="Hostname" placeholder="example.com" />
      </div>

      <div class="grid grid-cols-2 gap-4">
        <div>
          <.input
            field={@form[:record_type]}
            type="select"
            label="Record Type"
            options={["A", "AAAA", "CNAME", "MX", "TXT", "NS"]}
          />
        </div>
        <div>
          <.input
            field={@form[:dns_server]}
            type="text"
            label="DNS Server (optional)"
            placeholder="8.8.8.8"
          />
        </div>
      </div>

      <div>
        <.input
          field={@form[:expected_result]}
          type="text"
          label="Expected Result (optional)"
          placeholder="Expected IP or value"
        />
      </div>
    </div>
    """
  end

  @impl true
  def mount(socket) do
    {:ok, socket}
  end

  @impl true
  def update(assigns, socket) do
    changeset = Monitoring.change_check(%Monitoring.Check{})

    {:ok,
     socket
     |> assign(assigns)
     |> assign(:selected_type, "http")
     |> assign(:form, to_form(changeset))
     |> assign_default_config("http")}
  end

  @impl true
  def handle_event("change_type", %{"check" => %{"check_type" => type}}, socket) do
    {:noreply, socket |> assign(:selected_type, type) |> assign_default_config(type)}
  end

  @impl true
  def handle_event("validate", %{"check" => check_params}, socket) do
    check_params = merge_config_params(check_params, socket.assigns.selected_type)

    changeset =
      %Monitoring.Check{}
      |> Monitoring.change_check(check_params)
      |> Map.put(:action, :validate)

    {:noreply, assign(socket, form: to_form(changeset))}
  end

  @impl true
  def handle_event("save", %{"check" => check_params}, socket) do
    check_params = merge_config_params(check_params, socket.assigns.selected_type)

    check_params =
      check_params
      |> Map.put("organization_id", socket.assigns.device.organization_id)
      |> Map.put("device_id", socket.assigns.device.id)
      |> Map.put("source_type", "manual")

    case Monitoring.create_check(check_params) do
      {:ok, check} ->
        # Schedule first execution
        Monitoring.schedule_check(check)

        notify_parent({:check_created, check})
        {:noreply, socket}

      {:error, %Ecto.Changeset{} = changeset} ->
        {:noreply, assign(socket, form: to_form(changeset))}
    end
  end

  @impl true
  def handle_event("close", _params, socket) do
    notify_parent(:close)
    {:noreply, socket}
  end

  defp assign_default_config(socket, type) do
    config =
      case type do
        "http" ->
          %{
            "url" => "",
            "method" => "GET",
            "expected_status" => "200",
            "verify_ssl" => "true",
            "follow_redirects" => "true"
          }

        "tcp" ->
          %{"host" => "", "port" => ""}

        "dns" ->
          %{"hostname" => "", "record_type" => "A"}

        _ ->
          %{}
      end

    assign(socket, :default_config, config)
  end

  defp merge_config_params(check_params, type) do
    config =
      case type do
        "http" ->
          maybe_add(
            %{
              "url" => check_params["url"],
              "method" => check_params["method"] || "GET",
              "expected_status" => String.to_integer(check_params["expected_status"] || "200"),
              "verify_ssl" => check_params["verify_ssl"] == "true",
              "follow_redirects" => check_params["follow_redirects"] == "true"
            },
            "regex",
            check_params["content_match"]
          )

        "tcp" ->
          %{
            "host" => check_params["host"],
            "port" => String.to_integer(check_params["port"] || "0")
          }
          |> maybe_add("send", check_params["send_string"])
          |> maybe_add("expect", check_params["expect_string"])

        "dns" ->
          %{
            "hostname" => check_params["hostname"],
            "record_type" => check_params["record_type"] || "A"
          }
          |> maybe_add("server", check_params["dns_server"])
          |> maybe_add("expected", check_params["expected_result"])

        _ ->
          %{}
      end

    check_params
    |> Map.put("config", config)
    |> Map.put("check_type", type)
  end

  defp maybe_add(map, _key, nil), do: map
  defp maybe_add(map, _key, ""), do: map
  defp maybe_add(map, key, value), do: Map.put(map, key, value)

  defp notify_parent(msg), do: send(self(), {__MODULE__, msg})
end
