package cloud.nstart.terravault.ordinis.notifications.channel;

import cloud.nstart.terravault.ordinis.notifications.event.NotificationEvent;

/**
 * Channel adapter contract. Реализации:
 * <ul>
 *   <li>{@code EmailChannel} — JavaMailSender + multipart text+HTML.</li>
 *   <li>{@code ExpressChannel} — BotX bot API (Phase B).</li>
 *   <li>{@code TelegramChannel} — Bot API (Phase C).</li>
 * </ul>
 *
 * <p>Caller responsibility (NotificationDispatcher):
 * <ol>
 *   <li>IdempotencyGuard claim — INSERT ON CONFLICT DO NOTHING.</li>
 *   <li>Pref check — skip если disabled.</li>
 *   <li>Rate limit check — skip если exceeded.</li>
 *   <li>Render через MessageRenderer (sanitization built-in).</li>
 *   <li>Call {@link #dispatch(NotificationEvent, UserRef, RenderedMessage)}.</li>
 *   <li>Update notification_log status based on result.</li>
 * </ol>
 *
 * <p>Channel responsibility:
 * <ul>
 *   <li>Transport-level send (SMTP / HTTP).</li>
 *   <li>Channel-specific timeout enforcement.</li>
 *   <li>Return DispatchResult с error message если fail.</li>
 *   <li>NOT retry — outbox poller / replay handles retry semantics.</li>
 * </ul>
 */
public interface NotificationChannel {

  ChannelKind kind();

  /** True если channel конфигурирован (creds present, etc). False → channel skip'ится. */
  boolean isEnabled();

  /**
   * Send the rendered message к recipient.
   *
   * @param event original event для context (event_id для tracing, etc)
   * @param recipient resolved user ref (channel-specific identifier через
   *                  {@code recipient.recipientFor(kind())})
   * @param msg pre-rendered, pre-sanitized message
   * @return success/failure with optional error message
   */
  DispatchResult dispatch(NotificationEvent event, UserRef recipient, RenderedMessage msg);

  record DispatchResult(boolean ok, String errorMsg) {
    public static DispatchResult success() {
      return new DispatchResult(true, null);
    }

    public static DispatchResult failure(String errorMsg) {
      return new DispatchResult(false, errorMsg);
    }
  }
}
