defmodule Berrypod.Mailer.Adapters do
  @moduledoc """
  Registry of supported email adapters and their config shapes.

  Each adapter entry defines the fields needed for configuration.
  The UI renders dynamically from this registry. Adding a new adapter
  is just adding an entry here — no other code changes needed.
  """

  alias Berrypod.Mailer.{Adapter, Field}

  @adapters [
    # ── Also sends newsletters ──
    %Adapter{
      key: "brevo",
      name: "Brevo",
      module: Swoosh.Adapters.Brevo,
      description: "All-in-one platform, GDPR-friendly.",
      tags: ["All email", "France", "GDPR"],
      category: :all_email,
      recommended: true,
      free_tier: "300 emails/day free",
      setup_hint: "Paste one API key",
      url: "https://www.brevo.com",
      fields: [
        %Field{key: "api_key", label: "API key", type: :secret, required: true}
      ]
    },
    %Adapter{
      key: "sendgrid",
      name: "SendGrid",
      module: Swoosh.Adapters.Sendgrid,
      description: "Generous free tier, widely used.",
      tags: ["All email", "US"],
      category: :all_email,
      free_tier: "100 emails/day free",
      setup_hint: "Paste one API key",
      url: "https://sendgrid.com",
      fields: [
        %Field{key: "api_key", label: "API key", type: :secret, required: true}
      ]
    },
    %Adapter{
      key: "mailjet",
      name: "Mailjet",
      module: Swoosh.Adapters.Mailjet,
      description: "EU data processing, good free tier.",
      tags: ["All email", "France", "GDPR"],
      category: :all_email,
      free_tier: "200 emails/day free",
      setup_hint: "Two API keys needed",
      url: "https://www.mailjet.com",
      fields: [
        %Field{key: "api_key", label: "API key", type: :secret, required: true},
        %Field{key: "secret", label: "Secret key", type: :secret, required: true}
      ]
    },
    %Adapter{
      key: "mailersend",
      name: "MailerSend",
      module: Swoosh.Adapters.MailerSend,
      description: "Generous free tier, good analytics dashboard.",
      tags: ["All email", "EU option"],
      category: :all_email,
      free_tier: "3,000 emails/month free",
      setup_hint: "Paste one API key",
      url: "https://www.mailersend.com",
      fields: [
        %Field{key: "api_key", label: "API key", type: :secret, required: true}
      ]
    },
    # ── Advanced ──
    %Adapter{
      key: "smtp",
      name: "SMTP",
      module: Swoosh.Adapters.SMTP,
      description: "Connect to any email server via SMTP.",
      tags: ["All email", "Any provider"],
      category: :advanced,
      setup_hint: "Server details needed",
      fields: [
        %Field{key: "relay", label: "Server host", type: :string, required: true},
        %Field{key: "port", label: "Port", type: :integer, default: 587},
        %Field{key: "username", label: "Username", type: :string},
        %Field{key: "password", label: "Password", type: :secret}
      ]
    },
    %Adapter{
      key: "postal",
      name: "Postal",
      module: Swoosh.Adapters.Postal,
      description: "Full control over your email infrastructure.",
      tags: ["All email", "Self-hosted", "Open source"],
      category: :advanced,
      free_tier: "Self-hosted, no limits",
      setup_hint: "Requires your own server",
      url: "https://docs.postalserver.io",
      fields: [
        %Field{key: "api_key", label: "API key", type: :secret, required: true},
        %Field{key: "base_url", label: "Server URL", type: :string, required: true}
      ]
    }
  ]

  @doc "Returns all supported adapters."
  def all, do: @adapters

  @doc "Returns adapters grouped by category."
  def grouped do
    Enum.group_by(@adapters, & &1.category)
  end

  @doc "Returns an adapter by its string key, or nil."
  def get(key) when is_binary(key) do
    Enum.find(@adapters, &(&1.key == key))
  end

  @doc "Returns the namespaced settings key for an adapter field."
  def settings_key(adapter_key, field_key) do
    "email_#{adapter_key}_#{field_key}"
  end

  @doc "Returns the settings keys for an adapter's fields."
  def field_keys(%{key: adapter_key, fields: fields}) do
    Enum.map(fields, &settings_key(adapter_key, &1.key))
  end

  @doc "Returns all possible settings keys across all adapters."
  def all_field_keys do
    Enum.flat_map(@adapters, &field_keys/1)
  end
end
