defmodule MvWeb.ImportLive.Components do
  @moduledoc """
  Function components for the Import LiveView: import form, progress, results,
  custom fields notice, and template links. Keeps the main LiveView focused on
  mount/handle_event/handle_info and glue code.
  """
  use Phoenix.Component
  use Gettext, backend: MvWeb.Gettext

  import MvWeb.CoreComponents

  use Phoenix.VerifiedRoutes,
    endpoint: MvWeb.Endpoint,
    router: MvWeb.Router,
    statics: MvWeb.static_paths()

  @doc """
  Renders the info box explaining that data fields must exist before import
  and linking to Manage Member Data (custom fields).
  """
  def custom_fields_notice(assigns) do
    ~H"""
    <div role="note" class="alert alert-info mb-4">
      <.icon name="hero-information-circle" class="size-5" aria-hidden="true" />
      <div>
        <p class="text-sm mb-2">
          {gettext(
            "Use the data field name as the CSV column header in your file. Data fields must exist in Mila before importing, so they must be listed in the list of member data (like e-mail or first name). Unknown data field columns will be ignored with a warning."
          )}
        </p>
        <p class="text-sm">
          <.link
            href={~p"/settings#custom_fields"}
            class="link"
            data-testid="custom-fields-link"
          >
            {gettext("Manage Member Data")}
          </.link>
        </p>
      </div>
    </div>
    """
  end

  @doc """
  Renders download links for English and German CSV templates.
  """
  def template_links(assigns) do
    ~H"""
    <div class="mb-4">
      <p class="text-sm text-base-content/70 mb-2">
        {gettext("Download CSV templates:")}
      </p>
      <ul class="list-disc list-inside space-y-1">
        <li>
          <.link
            href={~p"/templates/member_import_en.csv"}
            download="member_import_en.csv"
            class="link link-primary"
          >
            {gettext("English Template")}
          </.link>
        </li>
        <li>
          <.link
            href={~p"/templates/member_import_de.csv"}
            download="member_import_de.csv"
            class="link link-primary"
          >
            {gettext("German Template")}
          </.link>
        </li>
      </ul>
    </div>
    """
  end

  @doc """
  Renders the CSV file upload form and Start Import button.
  """
  def import_form(assigns) do
    ~H"""
    <.form
      id="csv-upload-form"
      for={%{}}
      multipart={true}
      phx-change="validate_csv_upload"
      phx-submit="start_import"
      data-testid="csv-upload-form"
    >
      <div class="form-control">
        <label for="csv_file" class="label">
          <span class="label-text">
            {gettext("CSV File")}
          </span>
        </label>
        <.live_file_input
          upload={@uploads.csv_file}
          id="csv_file"
          class="file-input file-input-bordered w-full"
          aria-describedby="csv_file_help"
        />
        <p class="label-text-alt mt-1" id="csv_file_help">
          {gettext("CSV files only, maximum %{size} MB", size: @csv_import_max_file_size_mb)}
        </p>
      </div>

      <.button
        type="submit"
        phx-disable-with={gettext("Starting import...")}
        variant="primary"
        disabled={import_button_disabled?(@import_status, @uploads.csv_file.entries)}
        data-testid="start-import-button"
      >
        {gettext("Start Import")}
      </.button>
    </.form>
    """
  end

  @doc """
  Renders import progress text and, when done or aborted, the import results section.
  """
  def import_progress(assigns) do
    ~H"""
    <%= if @import_progress do %>
      <div
        role="status"
        aria-live="polite"
        aria-atomic="true"
        class="mt-4"
        data-testid="import-progress-container"
      >
        <%= if @import_progress.status == :running do %>
          <p class="text-sm" data-testid="import-progress-text">
            {gettext("Processing chunk %{current} of %{total}...",
              current: @import_progress.current_chunk,
              total: @import_progress.total_chunks
            )}
          </p>
        <% end %>

        <%= if @import_progress.status == :done or @import_status == :error do %>
          <.import_results {assigns} />
        <% end %>
      </div>
    <% end %>
    """
  end

  @doc """
  Renders import results summary, error list, and warnings.
  Shown when import is done or aborted (:error); heading reflects state.
  """
  def import_results(assigns) do
    ~H"""
    <section
      class="space-y-4"
      data-testid="import-results-panel"
      aria-labelledby="import-results-heading"
    >
      <h2
        id="import-results-heading"
        class="text-lg font-semibold"
        data-testid="import-results-heading"
      >
        <%= if @import_status == :error do %>
          {gettext("Import aborted")}
        <% else %>
          {gettext("Import Results")}
        <% end %>
      </h2>

      <div class="space-y-4">
        <div data-testid="import-summary">
          <h3 class="text-sm font-semibold mb-2">
            {gettext("Summary")}
          </h3>
          <div class="text-sm space-y-2">
            <p>
              <.icon
                name="hero-check-circle"
                class="size-4 inline mr-1"
                aria-hidden="true"
              />
              {gettext("Successfully inserted: %{count} member(s)",
                count: @import_progress.inserted
              )}
            </p>
            <%= if @import_progress.failed > 0 do %>
              <p>
                <.icon
                  name="hero-exclamation-circle"
                  class="size-4 inline mr-1"
                  aria-hidden="true"
                />
                {gettext("Failed: %{count} row(s)", count: @import_progress.failed)}
              </p>
            <% end %>
            <%= if @import_progress.errors_truncated? do %>
              <p>
                <.icon
                  name="hero-information-circle"
                  class="size-4 inline mr-1"
                  aria-hidden="true"
                />
                {gettext("Error list truncated to %{count} entries", count: @max_errors)}
              </p>
            <% end %>
          </div>
        </div>

        <%= if length(@import_progress.errors) > 0 do %>
          <div
            role="alert"
            aria-live="assertive"
            aria-atomic="true"
            data-testid="import-error-list"
          >
            <h3 class="text-sm font-semibold mb-2">
              <.icon
                name="hero-exclamation-circle"
                class="size-4 inline mr-1"
                aria-hidden="true"
              />
              {gettext("Errors")}
            </h3>
            <ul class="list-disc list-inside space-y-1 text-sm">
              <%= for error <- @import_progress.errors do %>
                <li>
                  {gettext("Line %{line}: %{message}",
                    line: error.csv_line_number || "?",
                    message: error.message || gettext("Unknown error")
                  )}
                  <%= if error.field do %>
                    {gettext(" (Field: %{field})", field: error.field)}
                  <% end %>
                </li>
              <% end %>
            </ul>
          </div>
        <% end %>

        <%= if length(@import_progress.warnings) > 0 do %>
          <div class="alert alert-warning" role="alert" data-testid="import-warnings">
            <.icon name="hero-information-circle" class="size-5" aria-hidden="true" />
            <div>
              <h3 class="font-semibold mb-2">
                {gettext("Warnings")}
              </h3>
              <ul class="list-disc list-inside space-y-1 text-sm">
                <%= for warning <- @import_progress.warnings do %>
                  <li>{warning}</li>
                <% end %>
              </ul>
            </div>
          </div>
        <% end %>
      </div>
    </section>
    """
  end

  @doc """
  Returns whether the Start Import button should be disabled.
  """
  @spec import_button_disabled?(:idle | :running | :done | :error, [map()]) :: boolean()
  def import_button_disabled?(:running, _entries), do: true
  def import_button_disabled?(_status, []), do: true
  def import_button_disabled?(_status, [entry | _]) when not entry.done?, do: true
  def import_button_disabled?(_status, _entries), do: false
end
