/**
 * Email Renderer Service
 *
 * Converts EmailBlock[] (visual template builder format) into
 * email-compatible HTML with inline styles, table-based layout,
 * and fallbacks for email clients that don't support modern CSS.
 *
 * Used by:
 * - emailDesignerTemplates route (/api/email-designer-templates/:id/render)
 * - SendEmailHandler in the automation workflow engine
 * - Any future endpoint that needs to render blocks to HTML
 */

import type { IEmailDesignerTemplate } from '../../models/EmailDesignerTemplate';

// ============================================
// PUBLIC API
// ============================================

/**
 * Render an EmailDesignerTemplate's blocks into a complete email HTML document.
 * If htmlOutput is already present and non-empty, returns it directly.
 */
export function renderTemplateToHtml(template: IEmailDesignerTemplate): string {
  // If already rendered, return cached HTML
  if (template.htmlOutput && template.htmlOutput.trim()) {
    return template.htmlOutput;
  }

  return renderBlocksToHtml({
    blocks: template.blocks || [],
    designSettings: template.designSettings || {},
    subject: template.subject || template.name || '',
  });
}

/**
 * Render raw blocks array + settings into a complete email HTML document.
 * Useful when you have blocks but not a full template document.
 */
export function renderBlocksToHtml(params: {
  blocks: any[];
  designSettings?: Record<string, any>;
  subject?: string;
}): string {
  const { blocks, designSettings = {}, subject } = params;

  const bgColor = designSettings.backgroundColor || '#1a1d21';
  const contentBgColor = designSettings.contentBackgroundColor || '#ffffff';
  const contentWidth = designSettings.contentWidth || 600;
  const fontFamily = designSettings.fontFamily || 'Arial, sans-serif';

  const blockHtmlParts: string[] = [];
  for (const block of blocks) {
    blockHtmlParts.push(renderSingleBlock(block));
  }

  return `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${escapeHtml(subject || 'Email')}</title>
  <!--[if !mso]><!-->
  <style type="text/css">
    body { margin:0; padding:0; }
    img { border:0; outline:none; text-decoration:none; }
    a { text-decoration:none; }
  </style>
  <!--<![endif]-->
</head>
<body style="margin:0;padding:0;background-color:${bgColor};font-family:${fontFamily};-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;">
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:${bgColor};">
    <tr>
      <td align="center" style="padding:20px 0;">
        <table role="presentation" width="${contentWidth}" cellpadding="0" cellspacing="0" border="0" style="background-color:${contentBgColor};max-width:${contentWidth}px;width:100%;border-radius:8px;overflow:hidden;">
          ${blockHtmlParts.join('\n')}
        </table>
      </td>
    </tr>
  </table>
</body>
</html>`;
}

/**
 * Render a single block to HTML (exported for testing/composition).
 */
export function renderSingleBlock(block: any): string {
  const type = block.type || '';
  const data = block.data || {};

  switch (type) {
    case 'heading':
      return renderHeading(data);
    case 'paragraph':
      return renderParagraph(data);
    case 'image':
      return renderImage(data);
    case 'button':
      return renderButton(data);
    case 'divider':
      return renderDivider(data);
    case 'spacer':
      return renderSpacer(data);
    case 'hero-banner':
      return renderHeroBanner(data);
    case 'logo':
      return renderLogo(data);
    case 'social-icons':
      return renderSocialIcons(data);
    case 'footer':
      return renderFooter(data);
    case 'html-block':
      return data.html || '';
    case 'product-card':
      return renderProductCard(data);
    case 'video-placeholder':
      return renderVideoPlaceholder(data);
    case 'two-columns':
      return renderColumns(data, 2);
    case 'three-columns':
      return renderColumns(data, 3);
    default:
      return `<!-- Unknown block type: ${escapeHtml(type)} -->`;
  }
}

// ============================================
// BLOCK RENDERERS
// ============================================

function renderHeading(data: any): string {
  const { text = '', level = 1, fontSize, fontWeight = 'bold', color = '#1a1a1a', alignment = 'left' } = data;
  const tag = `h${level}`;
  const size = fontSize ? `${fontSize}px` : (level === 1 ? '28px' : level === 2 ? '24px' : '20px');
  const padding = formatPadding(data.padding, { top: 10, right: 20, bottom: 10, left: 20 });

  return `<tr><td style="${padding}text-align:${alignment};">
  <${tag} style="margin:0;font-size:${size};font-weight:${fontWeight};color:${color};text-align:${alignment};line-height:1.3;">${escapeHtml(text)}</${tag}>
</td></tr>`;
}

function renderParagraph(data: any): string {
  const { text = '', fontSize = 16, lineHeight = 1.6, color = '#333333', alignment = 'left' } = data;
  const padding = formatPadding(data.padding, { top: 0, right: 20, bottom: 0, left: 20 });

  return `<tr><td style="${padding}font-size:${fontSize}px;line-height:${lineHeight};color:${color};text-align:${alignment};">${text}</td></tr>`;
}

function renderImage(data: any): string {
  const { src = '', alt = '', width = 'auto', height = 'auto', borderRadius = 0, alignment = 'center' } = data;
  const padding = formatPadding(data.padding, { top: 10, right: 20, bottom: 10, left: 20 });
  const wAttr = width !== 'auto' ? `width="${width}"` : '';
  const hAttr = height !== 'auto' ? `height="${height}"` : '';

  return `<tr><td align="${alignment}" style="${padding}">
  <img src="${escapeAttr(src)}" alt="${escapeAttr(alt)}" ${wAttr} ${hAttr} style="display:block;max-width:100%;border-radius:${borderRadius}px;" />
</td></tr>`;
}

function renderButton(data: any): string {
  const { text = 'Click Here', url = '', backgroundColor = '#C8FF2E', textColor = '#0d1117', borderRadius = 8, fontSize = 16, fontWeight = '600', alignment = 'center' } = data;
  const padding = formatPadding(data.padding, { top: 12, right: 24, bottom: 12, left: 24 });

  return `<tr><td align="${alignment}" style="${padding}">
  <!--[if mso]>
  <v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="${escapeAttr(url)}" style="height:${fontSize + 16}px;v-text-anchor:middle;width:auto;" arcsize="${Math.round((borderRadius / (fontSize + 16)) * 100)}%" fillcolor="${backgroundColor}" stroke="f">
    <w:anchorlock/><center style="color:${textColor};font-family:Arial,sans-serif;font-size:${fontSize}px;font-weight:${fontWeight};">${escapeHtml(text)}</center>
  </v:roundrect>
  <![endif]-->
  <!--[if !mso]><!-->
  <a href="${escapeAttr(url)}" style="display:inline-block;background-color:${backgroundColor};color:${textColor};font-size:${fontSize}px;font-weight:${fontWeight};text-decoration:none;border-radius:${borderRadius}px;padding:12px 28px;text-align:center;mso-padding-alt:0;text-underline-color:${backgroundColor};">${escapeHtml(text)}</a>
  <!--<![endif]-->
</td></tr>`;
}

function renderDivider(data: any): string {
  const { style = 'solid', color = '#e5e5e5', thickness = 1, width = '100%', alignment = 'center' } = data;
  const margin = data.margin || { top: 20, bottom: 20 };

  return `<tr><td style="padding-top:${margin.top || 20}px;padding-bottom:${margin.bottom || 20}px;text-align:${alignment};">
  <hr style="border:none;border-top:${thickness}px ${style} ${color};width:${width};margin:0;" />
</td></tr>`;
}

function renderSpacer(data: any): string {
  const height = data.height || 30;
  return `<tr><td style="height:${height}px;font-size:0;line-height:0;mso-line-height-rule:exactly;">&nbsp;</td></tr>`;
}

function renderHeroBanner(data: any): string {
  const {
    backgroundImage = '', overlayColor = '#000000', overlayOpacity = 0.5,
    title = '', subtitle = '', buttonText = '', buttonUrl = '',
    buttonBackgroundColor = '#C8FF2E', buttonTextColor = '#0d1117',
    alignment = 'center', height = 300,
  } = data;
  const padding = formatPadding(data.padding, { top: 60, right: 40, bottom: 60, left: 40 });

  // VML-based fallback for Outlook + background image for modern clients
  return `<tr><td align="${alignment}" background="${escapeAttr(backgroundImage)}" width="100%" style="${padding}background-image:url('${escapeAttr(backgroundImage)}');background-size:cover;background-position:center;text-align:${alignment};height:${height}px;background-color:${overlayColor};">
  <!--[if gte mso 9]>
  <v:rect style="height:${height}px" fill="true" stroke="false">
    <v:fill src="${escapeAttr(backgroundImage)}" type="frame"/>
    <v:textbox inset="0,0,0,0">
  <![endif]-->
  <div style="background:rgba(${hexToRgb(overlayColor)},${overlayOpacity});padding:${padding};max-width:100%;">
    ${title ? `<h1 style="margin:0 0 10px;color:#ffffff;font-size:28px;line-height:1.2;">${escapeHtml(title)}</h1>` : ''}
    ${subtitle ? `<p style="margin:0 0 20px;color:#ffffff;font-size:16px;line-height:1.5;">${escapeHtml(subtitle)}</p>` : ''}
    ${buttonText ? `<a href="${escapeAttr(buttonUrl)}" style="display:inline-block;background-color:${buttonBackgroundColor};color:${buttonTextColor};text-decoration:none;border-radius:8px;padding:12px 24px;font-weight:600;font-size:16px;">${escapeHtml(buttonText)}</a>` : ''}
  </div>
  <!--[if gte mso 9]>
    </v:textbox>
  </v:rect>
  <![endif]-->
</td></tr>`;
}

function renderLogo(data: any): string {
  const { src = '', width = 150, alignment = 'center' } = data;
  const padding = formatPadding(data.padding, { top: 20, right: 20, bottom: 20, left: 20 });

  return `<tr><td align="${alignment}" style="${padding}">
  <img src="${escapeAttr(src)}" alt="Logo" width="${width}" style="display:block;max-width:100%;height:auto;" />
</td></tr>`;
}

function renderSocialIcons(data: any): string {
  const { platforms = [], alignment = 'center', spacing = 12 } = data;
  const padding = formatPadding(data.padding, { top: 20, right: 20, bottom: 20, left: 20 });

  const iconLinks = platforms.map((p: any) => {
    const platformName = (p.platform || '').toLowerCase();
    const iconUrl = getSocialIconUrl(platformName);
    return `<a href="${escapeAttr(p.url || '#')}" style="display:inline-block;margin-left:${Math.floor(spacing / 2)}px;margin-right:${Math.floor(spacing / 2)}px;">
    <img src="${iconUrl}" alt="${escapeAttr(p.platform || 'Social')}" width="${p.iconSize || 24}" height="${p.iconSize || 24}" style="display:block;border:0;" />
  </a>`;
  }).join('\n');

  return `<tr><td align="${alignment}" style="${padding}">${iconLinks}</td></tr>`;
}

function renderFooter(data: any): string {
  const { companyName = '', address = '', backgroundColor = '#1a1d21', textColor = '#878e9a', fontSize = 12, alignment = 'center' } = data;
  const {
    showUnsubscribe = true, showPreferences = true, showViewInBrowser = true,
    unsubscribeUrl = '{{unsubscribe_link}}', preferencesUrl = '{{preferences_link}}',
    viewInBrowserUrl = '{{view_in_browser_link}}',
  } = data;
  const padding = formatPadding(data.padding, { top: 30, right: 20, bottom: 30, left: 20 });

  const links: string[] = [];
  if (showViewInBrowser) links.push(`<a href="${escapeAttr(viewInBrowserUrl)}" style="color:${textColor};text-decoration:underline;">View in browser</a>`);
  if (showPreferences) links.push(`<a href="${escapeAttr(preferencesUrl)}" style="color:${textColor};text-decoration:underline;">Preferences</a>`);
  if (showUnsubscribe) links.push(`<a href="${escapeAttr(unsubscribeUrl)}" style="color:${textColor};text-decoration:underline;">Unsubscribe</a>`);

  return `<tr><td style="background-color:${backgroundColor};${padding}text-align:${alignment};">
  ${companyName ? `<p style="margin:0 0 5px;color:${textColor};font-size:${fontSize}px;font-weight:bold;">${escapeHtml(companyName)}</p>` : ''}
  ${address ? `<p style="margin:0 0 10px;color:${textColor};font-size:${fontSize}px;">${escapeHtml(address)}</p>` : ''}
  <p style="margin:0;color:${textColor};font-size:${fontSize}px;">${links.join(' &middot; ')}</p>
</td></tr>`;
}

function renderProductCard(data: any): string {
  const { name = '', description = '', image = '', price = '', buttonText = 'Buy Now', buttonUrl = '', alignment = 'center' } = data;
  const padding = formatPadding(data.padding, { top: 20, right: 20, bottom: 20, left: 20 });

  return `<tr><td style="${padding}text-align:${alignment};">
  ${image ? `<img src="${escapeAttr(image)}" alt="${escapeAttr(name)}" style="display:block;max-width:100%;margin:0 auto;border-radius:8px;" />` : ''}
  <h3 style="margin:15px 0 5px;font-size:18px;color:#1a1a1a;">${escapeHtml(name)}</h3>
  ${description ? `<p style="margin:0 0 10px;font-size:14px;color:#666;line-height:1.5;">${escapeHtml(description)}</p>` : ''}
  ${price ? `<p style="margin:0 0 15px;font-size:20px;font-weight:bold;color:#1a1a1a;">${escapeHtml(price)}</p>` : ''}
  <a href="${escapeAttr(buttonUrl)}" style="display:inline-block;background-color:#C8FF2E;color:#0d1117;text-decoration:none;border-radius:8px;padding:10px 20px;font-weight:600;font-size:14px;">${escapeHtml(buttonText)}</a>
</td></tr>`;
}

function renderVideoPlaceholder(data: any): string {
  const { thumbnailImage = '', videoUrl = '', playButtonColor = '#C8FF2E', borderRadius = 8, alignment = 'center' } = data;
  const width = data.width || 556;
  const padding = formatPadding(data.padding, { top: 20, right: 20, bottom: 20, left: 20 });

  return `<tr><td align="${alignment}" style="${padding}">
  <a href="${escapeAttr(videoUrl)}" style="display:inline-block;position:relative;">
    <img src="${escapeAttr(thumbnailImage)}" alt="Video thumbnail" width="${width}" style="display:block;max-width:100%;border-radius:${borderRadius}px;" />
  </a>
</td></tr>`;
}

function renderColumns(data: any, numCols: number): string {
  const { columns = [], gap = numCols === 3 ? 15 : 20 } = data;
  const padding = formatPadding(data.padding, { top: 0, right: 20, bottom: 0, left: 20 });

  const columnCells = (columns as any[][]).map((colBlocks: any[]) => {
    const innerHtml = (colBlocks || []).map((b: any) => renderSingleBlock(b)).join('');
    return `<td valign="top" style="width:${Math.floor(100 / numCols)}%;padding:0 ${Math.floor(gap / 2)}px;">${innerHtml}</td>`;
  }).join('\n');

  return `<tr><td style="${padding}">
  <table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="width:100%;">
    <tr>${columnCells}</tr>
  </table>
</td></tr>`;
}

// ============================================
// UTILITY FUNCTIONS
// ============================================

function formatPadding(padding: any, defaults: { top: number; right: number; bottom: number; left: number }): string {
  const p = { ...defaults, ...(padding || {}) };
  return `padding:${p.top}px ${p.right}px ${p.bottom}px ${p.left}px;`;
}

function escapeHtml(str: string): string {
  if (!str) return '';
  return str
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;');
}

function escapeAttr(str: string): string {
  if (!str) return '';
  return str
    .replace(/&/g, '&amp;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;');
}

function hexToRgb(hex: string): string {
  const h = hex.replace('#', '');
  const r = parseInt(h.substring(0, 2), 16);
  const g = parseInt(h.substring(2, 4), 16);
  const b = parseInt(h.substring(4, 6), 16);
  return `${r},${g},${b}`;
}

function getSocialIconUrl(platform: string): string {
  const icons: Record<string, string> = {
    facebook: 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/facebook/facebook-icon.svg',
    twitter: 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/twitter/twitter-icon.svg',
    x: 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/x/x-icon.svg',
    linkedin: 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/linkedin/linkedin-icon.svg',
    instagram: 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/instagram/instagram-icon.svg',
    youtube: 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/youtube/youtube-icon.svg',
    tiktok: 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/tiktok/tiktok-icon.svg',
    pinterest: 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/pinterest/pinterest-icon.svg',
  };
  return icons[platform] || icons.facebook;
}