/**
 * Typed accessors for port-level configuration with env-fallback.
 *
 * Settings are stored in the `system_settings` table keyed by (key, portId).
 * The functions in this module resolve a port's effective configuration for
 * a given domain (email, Documenso, branding, reminders) by reading the
 * port-scoped row first, falling back to the global row, and finally to the
 * env var when neither is set.
 */
import { env } from '@/lib/env';
import { getSetting } from '@/lib/services/settings.service';

// ─── Setting key constants ───────────────────────────────────────────────────

export const SETTING_KEYS = {
  // Email
  emailFromName: 'email_from_name',
  emailFromAddress: 'email_from_address',
  emailReplyTo: 'email_reply_to',
  emailSignatureHtml: 'email_signature_html',
  emailFooterHtml: 'email_footer_html',
  emailAllowPersonalAccountSends: 'email_allow_personal_account_sends',
  smtpHostOverride: 'smtp_host_override',
  smtpPortOverride: 'smtp_port_override',
  smtpUserOverride: 'smtp_user_override',
  smtpPassOverride: 'smtp_pass_override',

  // Documenso / EOI
  documensoApiUrlOverride: 'documenso_api_url_override',
  documensoApiKeyOverride: 'documenso_api_key_override',
  documensoApiVersionOverride: 'documenso_api_version_override',
  documensoEoiTemplateId: 'documenso_eoi_template_id',
  eoiDefaultPathway: 'eoi_default_pathway',

  // Branding
  brandingLogoUrl: 'branding_logo_url',
  brandingPrimaryColor: 'branding_primary_color',
  brandingAppName: 'branding_app_name',
  brandingEmailHeaderHtml: 'branding_email_header_html',
  brandingEmailFooterHtml: 'branding_email_footer_html',

  // Reminders (port-level defaults)
  reminderDefaultDays: 'reminder_default_days',
  reminderDefaultEnabled: 'reminder_default_enabled',
  reminderDigestEnabled: 'reminder_digest_enabled',
  reminderDigestTime: 'reminder_digest_time',
  reminderDigestTimezone: 'reminder_digest_timezone',
} as const;

// ─── Helper ──────────────────────────────────────────────────────────────────

async function readSetting<T>(key: string, portId: string): Promise<T | null> {
  const setting = await getSetting(key, portId);
  if (!setting) return null;
  return setting.value as T;
}

// ─── Email ──────────────────────────────────────────────────────────────────

export interface PortEmailConfig {
  fromName: string;
  fromAddress: string;
  replyTo: string | null;
  signatureHtml: string | null;
  footerHtml: string | null;
  smtpHost: string;
  smtpPort: number;
  smtpUser: string | null;
  smtpPass: string | null;
  /**
   * When false, only the system (port-config) sender identity is allowed.
   * When true, admins/users may send via their connected personal email
   * account. Defaults to false for safety.
   */
  allowPersonalAccountSends: boolean;
}

export async function getPortEmailConfig(portId: string): Promise<PortEmailConfig> {
  const [
    fromName,
    fromAddress,
    replyTo,
    signatureHtml,
    footerHtml,
    smtpHost,
    smtpPort,
    smtpUser,
    smtpPass,
    allowPersonalAccountSends,
  ] = await Promise.all([
    readSetting<string>(SETTING_KEYS.emailFromName, portId),
    readSetting<string>(SETTING_KEYS.emailFromAddress, portId),
    readSetting<string>(SETTING_KEYS.emailReplyTo, portId),
    readSetting<string>(SETTING_KEYS.emailSignatureHtml, portId),
    readSetting<string>(SETTING_KEYS.emailFooterHtml, portId),
    readSetting<string>(SETTING_KEYS.smtpHostOverride, portId),
    readSetting<number>(SETTING_KEYS.smtpPortOverride, portId),
    readSetting<string>(SETTING_KEYS.smtpUserOverride, portId),
    readSetting<string>(SETTING_KEYS.smtpPassOverride, portId),
    readSetting<boolean>(SETTING_KEYS.emailAllowPersonalAccountSends, portId),
  ]);

  // Parse env.SMTP_FROM into name + address if no port override
  let envFromName = 'Port Nimara CRM';
  let envFromAddress = `noreply@${env.SMTP_HOST}`;
  if (env.SMTP_FROM) {
    const match = env.SMTP_FROM.match(/^(.+?)\s*<(.+)>$/);
    if (match) {
      envFromName = match[1]!.trim();
      envFromAddress = match[2]!.trim();
    } else {
      envFromAddress = env.SMTP_FROM;
    }
  }

  return {
    fromName: fromName ?? envFromName,
    fromAddress: fromAddress ?? envFromAddress,
    replyTo: replyTo ?? null,
    signatureHtml: signatureHtml ?? null,
    footerHtml: footerHtml ?? null,
    smtpHost: smtpHost ?? env.SMTP_HOST,
    smtpPort: smtpPort ?? env.SMTP_PORT,
    smtpUser: smtpUser ?? env.SMTP_USER ?? null,
    smtpPass: smtpPass ?? env.SMTP_PASS ?? null,
    allowPersonalAccountSends: allowPersonalAccountSends ?? false,
  };
}

// ─── Documenso ──────────────────────────────────────────────────────────────

export type EoiPathway = 'documenso-template' | 'inapp';
export type DocumensoApiVersion = 'v1' | 'v2';

export interface PortDocumensoConfig {
  apiUrl: string;
  apiKey: string;
  apiVersion: DocumensoApiVersion;
  eoiTemplateId: string | null;
  defaultPathway: EoiPathway;
}

export async function getPortDocumensoConfig(portId: string): Promise<PortDocumensoConfig> {
  const [apiUrl, apiKey, apiVersion, eoiTemplateId, defaultPathway] = await Promise.all([
    readSetting<string>(SETTING_KEYS.documensoApiUrlOverride, portId),
    readSetting<string>(SETTING_KEYS.documensoApiKeyOverride, portId),
    readSetting<DocumensoApiVersion>(SETTING_KEYS.documensoApiVersionOverride, portId),
    readSetting<string>(SETTING_KEYS.documensoEoiTemplateId, portId),
    readSetting<EoiPathway>(SETTING_KEYS.eoiDefaultPathway, portId),
  ]);

  return {
    apiUrl: apiUrl ?? env.DOCUMENSO_API_URL,
    apiKey: apiKey ?? env.DOCUMENSO_API_KEY,
    apiVersion: apiVersion ?? env.DOCUMENSO_API_VERSION,
    eoiTemplateId: eoiTemplateId ?? null,
    defaultPathway: defaultPathway ?? 'documenso-template',
  };
}

// ─── Branding ───────────────────────────────────────────────────────────────

export interface PortBrandingConfig {
  logoUrl: string | null;
  primaryColor: string;
  appName: string;
  emailHeaderHtml: string | null;
  emailFooterHtml: string | null;
}

const DEFAULT_BRANDING: PortBrandingConfig = {
  logoUrl: null,
  primaryColor: '#1e293b',
  appName: 'Port Nimara CRM',
  emailHeaderHtml: null,
  emailFooterHtml: null,
};

export async function getPortBrandingConfig(portId: string): Promise<PortBrandingConfig> {
  const [logoUrl, primaryColor, appName, emailHeaderHtml, emailFooterHtml] = await Promise.all([
    readSetting<string>(SETTING_KEYS.brandingLogoUrl, portId),
    readSetting<string>(SETTING_KEYS.brandingPrimaryColor, portId),
    readSetting<string>(SETTING_KEYS.brandingAppName, portId),
    readSetting<string>(SETTING_KEYS.brandingEmailHeaderHtml, portId),
    readSetting<string>(SETTING_KEYS.brandingEmailFooterHtml, portId),
  ]);

  return {
    logoUrl: logoUrl ?? DEFAULT_BRANDING.logoUrl,
    primaryColor: primaryColor ?? DEFAULT_BRANDING.primaryColor,
    appName: appName ?? DEFAULT_BRANDING.appName,
    emailHeaderHtml: emailHeaderHtml ?? DEFAULT_BRANDING.emailHeaderHtml,
    emailFooterHtml: emailFooterHtml ?? DEFAULT_BRANDING.emailFooterHtml,
  };
}

// ─── Reminders ──────────────────────────────────────────────────────────────

export interface PortReminderConfig {
  defaultDays: number;
  defaultEnabled: boolean;
  digestEnabled: boolean;
  digestTime: string; // 'HH:MM'
  digestTimezone: string;
}

const DEFAULT_REMINDER: PortReminderConfig = {
  defaultDays: 7,
  defaultEnabled: false,
  digestEnabled: false,
  digestTime: '09:00',
  digestTimezone: 'Europe/Warsaw',
};

export async function getPortReminderConfig(portId: string): Promise<PortReminderConfig> {
  const [defaultDays, defaultEnabled, digestEnabled, digestTime, digestTimezone] =
    await Promise.all([
      readSetting<number>(SETTING_KEYS.reminderDefaultDays, portId),
      readSetting<boolean>(SETTING_KEYS.reminderDefaultEnabled, portId),
      readSetting<boolean>(SETTING_KEYS.reminderDigestEnabled, portId),
      readSetting<string>(SETTING_KEYS.reminderDigestTime, portId),
      readSetting<string>(SETTING_KEYS.reminderDigestTimezone, portId),
    ]);

  return {
    defaultDays: defaultDays ?? DEFAULT_REMINDER.defaultDays,
    defaultEnabled: defaultEnabled ?? DEFAULT_REMINDER.defaultEnabled,
    digestEnabled: digestEnabled ?? DEFAULT_REMINDER.digestEnabled,
    digestTime: digestTime ?? DEFAULT_REMINDER.digestTime,
    digestTimezone: digestTimezone ?? DEFAULT_REMINDER.digestTimezone,
  };
}
