/**
 * Branded layout + interpolation. Wraps a body fragment with a header
 * (restaurant brand for customer mail, platform brand otherwise) and
 * a "Powered by {adminBrand}" footer (always shown).
 */

import { db } from '@server/db/drizzle';
import { sql } from 'drizzle-orm';
import { DEFAULT_TEMPLATES, getDefaultTemplate, type TemplateDefault } from './templates';
import { getPlatformSetting } from './platform-settings';

export function escapeHtml(text: string): string {
  return String(text ?? '')
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');
}

/**
 * Replaces {{var}} tokens. Values are HTML-escaped by default so untrusted
 * user input (customer names, etc.) cannot inject markup into emails.
 *
 * Opt-out: variable names that end with `Html` or `html` are treated as
 * pre-rendered HTML fragments and inserted verbatim. The format helpers in
 * format.ts (formatOrderItemsHtml, formatOrderSummaryHtml, etc.) escape
 * untrusted fields themselves before composing HTML.
 */
export function interpolate(template: string, vars: Record<string, unknown>): string {
  return template.replace(/\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/g, (_m, key) => {
    const v = vars[key];
    if (v === undefined || v === null) return '';
    const isRawHtml = /[Hh]tml$/.test(key);
    return isRawHtml ? String(v) : escapeHtml(String(v));
  });
}

export interface BrandContext {
  appName: string;
  appUrl: string;
  logoUrl?: string;
  primaryColor: string;
  poweredByName: string;
  poweredByUrl?: string;
  poweredByLogoUrl?: string;
  /** When set, header uses restaurant identity (customer-facing). */
  restaurant?: { name: string; logoUrl?: string | null; primaryColor?: string | null };
}

export async function loadBrandContext(restaurantId?: string | null): Promise<BrandContext> {
  const appUrl = process.env.NEXT_PUBLIC_APP_URL || 'https://app.restroagent.com';

  const [appName, logo, primary, poweredByName, poweredByUrl, poweredByLogoUrl] = await Promise.all([
    getPlatformSetting<string>('site_title', 'RestroAgent'),
    getPlatformSetting<string>('site_logo_url', ''),
    getPlatformSetting<string>('site_primary_color', '#f97316'),
    getPlatformSetting<string>('admin_brand_name', 'diploy'),
    getPlatformSetting<string>('admin_brand_url', 'https://diploy.in'),
    getPlatformSetting<string>('admin_brand_logo_url', ''),
  ]);

  let restaurant: BrandContext['restaurant'];
  if (restaurantId) {
    try {
      const { rows } = await db.execute(sql`SELECT name, logo_url, primary_color FROM restaurants WHERE id = ${restaurantId} LIMIT 1`);
      const r = rows[0] as { name?: string; logo_url?: string; primary_color?: string } | undefined;
      if (r) restaurant = { name: r.name || '', logoUrl: r.logo_url, primaryColor: r.primary_color };
    } catch { /* ignore */ }
  }

  return {
    appName: appName || 'RestroAgent',
    appUrl,
    logoUrl: logo || undefined,
    primaryColor: primary || '#f97316',
    poweredByName: poweredByName || 'diploy',
    poweredByUrl: poweredByUrl || undefined,
    poweredByLogoUrl: poweredByLogoUrl || undefined,
    restaurant,
  };
}

export function wrapLayout(
  bodyHtml: string,
  audience: TemplateDefault['audience'],
  brand: BrandContext,
): string {
  const useRestaurant = audience === 'customer' && brand.restaurant;
  const headerName = useRestaurant ? brand.restaurant!.name : brand.appName;
  const headerLogo = useRestaurant ? brand.restaurant!.logoUrl : brand.logoUrl;
  const accent = useRestaurant ? (brand.restaurant!.primaryColor || brand.primaryColor) : brand.primaryColor;

  const logoHtml = headerLogo
    ? `<img src="${escapeHtml(headerLogo)}" alt="${escapeHtml(headerName)}" style="height:36px;max-width:160px;object-fit:contain;" />`
    : `<div style="font-size:20px;font-weight:700;color:#111827;letter-spacing:-0.5px;">${escapeHtml(headerName)}</div>`;

  const poweredByLabel = brand.poweredByLogoUrl
    ? `<img src="${escapeHtml(brand.poweredByLogoUrl)}" alt="${escapeHtml(brand.poweredByName)}" style="height:14px;vertical-align:middle;margin-left:4px;" />`
    : escapeHtml(brand.poweredByName);
  const poweredBy = brand.poweredByUrl
    ? `Powered by <a href="${escapeHtml(brand.poweredByUrl)}" style="color:#6b7280;text-decoration:underline;">${poweredByLabel}</a>`
    : `Powered by ${poweredByLabel}`;

  return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body style="margin:0;padding:0;background-color:#f4f4f5;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">
<table width="100%" cellpadding="0" cellspacing="0" style="background:#f4f4f5;padding:32px 16px;">
  <tr><td align="center">
    <table width="560" cellpadding="0" cellspacing="0" style="max-width:560px;width:100%;background:#fff;border-radius:16px;box-shadow:0 1px 3px rgba(0,0,0,0.05);overflow:hidden;">
      <tr><td style="padding:24px 32px;border-bottom:4px solid ${escapeHtml(accent)};">${logoHtml}</td></tr>
      <tr><td style="padding:28px 32px;">${bodyHtml}</td></tr>
      <tr><td style="padding:18px 32px;background:#fafafa;border-top:1px solid #f0f0f0;text-align:center;font-size:12px;color:#9ca3af;">
        &copy; ${new Date().getFullYear()} ${escapeHtml(headerName)} &middot; ${poweredBy}
      </td></tr>
    </table>
  </td></tr>
</table>
</body></html>`;
}

export interface ResolvedTemplate {
  subject: string;
  html: string;
  audience: TemplateDefault['audience'];
}

/** Loads template (admin override → default), interpolates, wraps. */
export async function renderTemplate(
  key: string,
  vars: Record<string, unknown>,
  restaurantId?: string | null,
  overrides?: { subject?: string; html?: string },
): Promise<ResolvedTemplate> {
  const def = getDefaultTemplate(key);
  if (!def) throw new Error(`Unknown email template: ${key}`);

  let subject = def.subject;
  let body = def.body;

  if (overrides?.subject || overrides?.html) {
    if (overrides.subject) subject = overrides.subject;
    if (overrides.html) body = overrides.html;
  } else {
    try {
      const { rows } = await db.execute(sql`SELECT subject, html FROM email_templates WHERE key = ${key} LIMIT 1`);
      const row = rows[0] as { subject?: string; html?: string } | undefined;
      if (row) {
        if (row.subject) subject = row.subject;
        if (row.html) body = row.html;
      }
    } catch { /* table may not exist on first boot */ }
  }

  const brand = await loadBrandContext(restaurantId);
  const merged = { ...vars, appName: brand.appName, appUrl: brand.appUrl, restaurantName: brand.restaurant?.name || vars.restaurantName || brand.appName };
  return {
    subject: interpolate(subject, merged),
    html: wrapLayout(interpolate(body, merged), def.audience, brand),
    audience: def.audience,
  };
}

export { DEFAULT_TEMPLATES };
