/**
 * Per-category email send-from routing.
 *
 * Each outbound email category (account activation, EOI signing request,
 * brochure send, etc.) resolves to a `SenderAccount` - `noreply` for
 * automation-shaped traffic, `sales` for human-touch traffic. The
 * mapping is admin-configurable per port via the `email_routing`
 * system_setting (JSONB blob).
 *
 * When a category routes to `sales` but the port has no configured
 * sales account (no SMTP creds in `sales_email_config` settings),
 * the resolver transparently falls back to `noreply` so a half-
 * configured port still sends rather than throwing. Admin UI
 * surfaces this by disabling the `sales` option when creds are
 * absent.
 *
 * Defaults follow CLAUDE.md: auth/notifications/EOI-invite → noreply;
 * brochure/berth-PDF/signed-doc completion/sales send-out → sales.
 */

import { getSetting } from '@/lib/services/settings.service';
import { getSalesEmailConfig, type SenderAccount } from '@/lib/services/sales-email-config.service';

export const EMAIL_CATEGORIES = [
  'account_activation',
  'password_reset',
  'notification_digest',
  'eoi_signing_request',
  'reservation_signing_request',
  'contract_signing_request',
  'brochure_send',
  'berth_pdf_send',
  'signed_doc_completion',
  'sales_sendout',
  'manual_compose',
  'inquiry_confirmation',
  'inquiry_sales_notification',
  'crm_invite',
  'admin_email_change',
  'gdpr_export',
  'system_other',
] as const;

export type EmailCategory = (typeof EMAIL_CATEGORIES)[number];

/**
 * Default sender per category. Categories not listed here fall back to
 * `noreply`. The admin UI seeds the routing matrix from this map on
 * first open.
 */
export const DEFAULT_CATEGORY_ROUTING: Record<EmailCategory, SenderAccount> = {
  account_activation: 'noreply',
  password_reset: 'noreply',
  notification_digest: 'noreply',
  eoi_signing_request: 'noreply',
  reservation_signing_request: 'noreply',
  contract_signing_request: 'noreply',
  brochure_send: 'sales',
  berth_pdf_send: 'sales',
  signed_doc_completion: 'sales',
  sales_sendout: 'sales',
  manual_compose: 'sales',
  inquiry_confirmation: 'noreply',
  inquiry_sales_notification: 'noreply',
  crm_invite: 'noreply',
  admin_email_change: 'noreply',
  gdpr_export: 'noreply',
  system_other: 'noreply',
};

export const EMAIL_ROUTING_KEY = 'email_routing';

/**
 * Resolve which sender account a given category should use for this
 * port. Reads the per-port `email_routing` JSONB blob; falls back to
 * the default mapping when unset, malformed, or missing the key.
 * Further falls back to `noreply` if the resolved sender is `sales`
 * but the port has no sales SMTP credentials configured (so a half-
 * configured port still sends through noreply rather than throwing).
 */
export async function resolveSenderForCategory(
  portId: string,
  category: EmailCategory,
): Promise<SenderAccount> {
  const setting = await getSetting(EMAIL_ROUTING_KEY, portId);
  let configured: SenderAccount = DEFAULT_CATEGORY_ROUTING[category];
  if (setting && typeof setting.value === 'object' && setting.value !== null) {
    const routing = setting.value as Record<string, string>;
    const v = routing[category];
    if (v === 'noreply' || v === 'sales') {
      configured = v;
    }
  }

  if (configured === 'sales') {
    const sales = await getSalesEmailConfig(portId);
    if (!sales.isUsable) {
      return 'noreply';
    }
  }
  return configured;
}

/**
 * Bulk-resolve the whole routing matrix for the admin UI. Returns the
 * effective mapping (defaults overlaid with whatever the port has
 * configured) plus an `isSalesAvailable` flag the UI uses to disable
 * the `sales` option when no creds are set.
 */
export async function getEmailRoutingMatrix(portId: string): Promise<{
  routing: Record<EmailCategory, SenderAccount>;
  isSalesAvailable: boolean;
}> {
  const [setting, sales] = await Promise.all([
    getSetting(EMAIL_ROUTING_KEY, portId),
    getSalesEmailConfig(portId),
  ]);
  const stored =
    setting && typeof setting.value === 'object' && setting.value !== null
      ? (setting.value as Record<string, string>)
      : {};

  const routing = { ...DEFAULT_CATEGORY_ROUTING };
  for (const cat of EMAIL_CATEGORIES) {
    const v = stored[cat];
    if (v === 'noreply' || v === 'sales') {
      routing[cat] = v;
    }
  }
  return { routing, isSalesAvailable: sales.isUsable };
}
