defmodule MvWeb.MembershipFeeSettingsLive do
  @moduledoc """
  LiveView for managing membership fee settings (Admin).

  Allows administrators to configure:
  - Default membership fee type for new members
  - Whether to include the joining cycle in membership fee generation
  """
  use MvWeb, :live_view

  import MvWeb.LiveHelpers, only: [current_actor: 1]

  alias Mv.Membership
  alias Mv.MembershipFees.MembershipFeeType

  @impl true
  def mount(_params, _session, socket) do
    actor = current_actor(socket)
    {:ok, settings} = Membership.get_settings()

    membership_fee_types =
      MembershipFeeType
      |> Ash.Query.sort(name: :asc)
      |> Ash.read!(domain: Mv.MembershipFees, actor: actor)

    {:ok,
     socket
     |> assign(:page_title, gettext("Membership Fee Settings"))
     |> assign(:settings, settings)
     |> assign(:membership_fee_types, membership_fee_types)
     |> assign_form()}
  end

  @impl true
  def handle_event("validate", %{"settings" => params}, socket) do
    # Normalize checkbox value: "on" -> true, missing -> false
    normalized_params =
      if Map.has_key?(params, "include_joining_cycle") do
        params
        |> Map.update("include_joining_cycle", false, fn
          "on" -> true
          "true" -> true
          true -> true
          _ -> false
        end)
      else
        Map.put(params, "include_joining_cycle", false)
      end

    {:noreply,
     assign(socket, form: AshPhoenix.Form.validate(socket.assigns.form, normalized_params))}
  end

  def handle_event("save", %{"settings" => params}, socket) do
    # Normalize checkbox value: "on" -> true, missing -> false
    normalized_params =
      if Map.has_key?(params, "include_joining_cycle") do
        params
        |> Map.update("include_joining_cycle", false, fn
          "on" -> true
          "true" -> true
          true -> true
          _ -> false
        end)
      else
        Map.put(params, "include_joining_cycle", false)
      end

    actor = MvWeb.LiveHelpers.current_actor(socket)

    case MvWeb.LiveHelpers.submit_form(socket.assigns.form, normalized_params, actor) do
      {:ok, updated_settings} ->
        {:noreply,
         socket
         |> assign(:settings, updated_settings)
         |> put_flash(:info, gettext("Settings saved successfully."))
         |> assign_form()}

      {:error, form} ->
        {:noreply, assign(socket, form: form)}
    end
  end

  @impl true
  def render(assigns) do
    ~H"""
    <Layouts.app flash={@flash} current_user={@current_user}>
      <.header>
        {gettext("Membership Fee Settings")}
        <:subtitle>
          {gettext("Configure global settings for membership fees.")}
        </:subtitle>
      </.header>

      <div class="grid gap-6 lg:grid-cols-2">
        <%!-- Settings Form --%>
        <div class="card bg-base-100 shadow-xl">
          <div class="card-body">
            <h2 class="card-title">
              <.icon name="hero-cog-6-tooth" class="size-5" />
              {gettext("Global Settings")}
            </h2>

            <.form
              for={@form}
              phx-change="validate"
              phx-submit="save"
              class="space-y-6"
            >
              <%!-- Default Membership Fee Type --%>
              <fieldset class="fieldset">
                <label for="default_membership_fee_type_id" class="label">
                  <span class="label-text font-semibold">
                    {gettext("Default Membership Fee Type")}
                  </span>
                </label>
                <select
                  id="default_membership_fee_type_id"
                  name="settings[default_membership_fee_type_id]"
                  class={[
                    "select select-bordered w-full",
                    if(@form.errors[:default_membership_fee_type_id], do: "select-error", else: "")
                  ]}
                  phx-debounce="blur"
                  aria-label={gettext("Default Membership Fee Type")}
                >
                  <option value="">{gettext("None (no default)")}</option>
                  <option
                    :for={fee_type <- @membership_fee_types}
                    value={fee_type.id}
                    selected={fee_type.id == @form[:default_membership_fee_type_id].value}
                  >
                    {fee_type.name} ({format_currency(fee_type.amount)}, {format_interval(
                      fee_type.interval
                    )})
                  </option>
                </select>
                <%= if @form.errors[:default_membership_fee_type_id] do %>
                  <%= for error <- List.wrap(@form.errors[:default_membership_fee_type_id]) do %>
                    <% {msg, _opts} = if is_tuple(error), do: error, else: {error, []} %>
                    <p class="text-error text-sm mt-1">{msg}</p>
                  <% end %>
                <% end %>
                <p class="text-sm text-base-content/60 mt-2">
                  {gettext(
                    "This membership fee type is automatically assigned to all new members. Can be changed individually per member."
                  )}
                </p>
              </fieldset>

              <%!-- Include Joining Cycle --%>
              <fieldset class="fieldset">
                <label class="label cursor-pointer justify-start gap-3">
                  <input
                    type="checkbox"
                    name="settings[include_joining_cycle]"
                    class="checkbox checkbox-primary"
                    checked={@form[:include_joining_cycle].value}
                    phx-debounce="blur"
                  />
                  <span class="label-text font-semibold">
                    {gettext("Include joining cycle")}
                  </span>
                </label>
                <%= if @form.errors[:include_joining_cycle] do %>
                  <%= for error <- List.wrap(@form.errors[:include_joining_cycle]) do %>
                    <% {msg, _opts} = if is_tuple(error), do: error, else: {error, []} %>
                    <p class="text-error text-sm ml-9 mt-1">{msg}</p>
                  <% end %>
                <% end %>
                <div class="ml-9 space-y-2">
                  <p class="text-sm text-base-content/60">
                    {gettext("When active: Members pay from the cycle of their joining.")}
                  </p>
                  <p class="text-sm text-base-content/60">
                    {gettext("When inactive: Members pay from the next full cycle after joining.")}
                  </p>
                </div>
              </fieldset>

              <div class="divider"></div>

              <button type="submit" class="btn btn-primary w-full">
                <.icon name="hero-check" class="size-5" />
                {gettext("Save Settings")}
              </button>
            </.form>
          </div>
        </div>

        <%!-- Examples Card --%>
        <div class="card bg-base-200">
          <div class="card-body">
            <h2 class="card-title">
              <.icon name="hero-light-bulb" class="size-5" />
              {gettext("Examples")}
            </h2>

            <.example_section
              title={gettext("Yearly Interval - Joining Cycle Included")}
              joining_date="15.03.2023"
              include_joining={true}
              start_date="01.01.2023"
              periods={["2023", "2024", "2025"]}
              note={gettext("Member pays for the year they joined")}
            />

            <div class="divider"></div>

            <.example_section
              title={gettext("Yearly Interval - Joining Cycle Excluded")}
              joining_date="15.03.2023"
              include_joining={false}
              start_date="01.01.2024"
              periods={["2024", "2025"]}
              note={gettext("Member pays from the next full year")}
            />

            <div class="divider"></div>

            <.example_section
              title={gettext("Quarterly Interval - Joining Cycle Excluded")}
              joining_date="15.05.2024"
              include_joining={false}
              start_date="01.07.2024"
              periods={["Q3/2024", "Q4/2024", "Q1/2025"]}
              note={gettext("Member pays from the next full quarter")}
            />

            <div class="divider"></div>

            <.example_section
              title={gettext("Monthly Interval - Joining Cycle Included")}
              joining_date="15.03.2024"
              include_joining={true}
              start_date="01.03.2024"
              periods={["03/2024", "04/2024", "05/2024", "..."]}
              note={gettext("Member pays from the joining month")}
            />
          </div>
        </div>
      </div>
    </Layouts.app>
    """
  end

  # Example section component
  attr :title, :string, required: true
  attr :joining_date, :string, required: true
  attr :include_joining, :boolean, required: true
  attr :start_date, :string, required: true
  attr :periods, :list, required: true
  attr :note, :string, required: true

  defp example_section(assigns) do
    ~H"""
    <div class="space-y-2">
      <h3 class="font-semibold text-sm">{@title}</h3>
      <div class="bg-base-300 rounded-lg p-3 text-sm space-y-1">
        <p>
          <span class="text-base-content/80">{gettext("Joining date")}:</span>
          <span class="font-mono">{@joining_date}</span>
        </p>
        <p>
          <span class="text-base-content/80">{gettext("Membership fee start")}:</span>
          <span class="font-mono font-semibold text-base-content">{@start_date}</span>
        </p>
        <p>
          <span class="text-base-content/80">{gettext("Generated cycles")}:</span>
          <span class="font-mono">
            {Enum.join(@periods, ", ")}
          </span>
        </p>
      </div>
      <p class="text-xs text-base-content/80 italic">→ {@note}</p>
    </div>
    """
  end

  defp format_currency(%Decimal{} = amount) do
    "#{Decimal.to_string(amount)} €"
  end

  defp format_interval(:monthly), do: gettext("Monthly")
  defp format_interval(:quarterly), do: gettext("Quarterly")
  defp format_interval(:half_yearly), do: gettext("Half-yearly")
  defp format_interval(:yearly), do: gettext("Yearly")

  defp assign_form(%{assigns: %{settings: settings}} = socket) do
    form =
      AshPhoenix.Form.for_update(
        settings,
        :update_membership_fee_settings,
        api: Membership,
        as: "settings",
        forms: [auto?: true]
      )

    assign(socket, form: to_form(form))
  end
end
