import type { FeatureIconKind, BrandVertical } from "@/lib/generation/brand-visual-style";
import type { SocialImageContext } from "@/lib/generation/social-image";

export function escapeXml(value: string): string {
  return value
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;");
}

export function wrapText(text: string, maxChars: number, maxLines: number): string[] {
  const words = text.split(/\s+/).filter(Boolean);
  const lines: string[] = [];
  let current = "";

  for (const word of words) {
    const next = current ? `${current} ${word}` : word;
    if (next.length > maxChars && current) {
      lines.push(current);
      current = word;
    } else {
      current = next;
    }
    if (lines.length >= maxLines) break;
  }

  if (lines.length < maxLines && current) lines.push(current);
  return lines.slice(0, maxLines);
}

export function multilineTextSvg(
  x: number,
  y: number,
  lines: string[],
  opts: {
    fontSize: number;
    fill: string;
    lineHeight: number;
    fontWeight?: string;
    anchor?: "start" | "middle";
  },
): string {
  if (!lines.length) return "";
  const weight = opts.fontWeight ?? "normal";
  const anchor = opts.anchor ? ` text-anchor="${opts.anchor}"` : "";
  const tspans = lines
    .map(
      (line, i) =>
        `<tspan x="${x}" dy="${i === 0 ? 0 : opts.lineHeight}">${escapeXml(line)}</tspan>`,
    )
    .join("");
  return `<text x="${x}" y="${y}" fill="${opts.fill}" font-family="Arial,Helvetica,sans-serif" font-size="${opts.fontSize}" font-weight="${weight}"${anchor}>${tspans}</text>`;
}

export function buildLogoBlock(
  ctx: SocialImageContext,
  opts: { x: number; y: number; maxWidth: number; maxHeight: number },
): string {
  // Exact logo is stamped by FFmpeg after rasterize (FFmpeg cannot render SVG data-URL images).
  // Reserve empty space only — no white/dark plate (those looked like stickers).
  if (ctx.logoDataUrl) {
    return `<!-- logo-safe zone x=${opts.x} y=${opts.y} w=${opts.maxWidth} h=${opts.maxHeight} -->`;
  }
  return `<text x="${opts.x}" y="${opts.y + 44}" fill="${ctx.brandStyle.primaryColor}" font-family="Arial,Helvetica,sans-serif" font-size="36" font-weight="bold">${escapeXml(ctx.companyName)}</text>`;
}

export function featureIconSvg(
  vertical: BrandVertical,
  kind: FeatureIconKind,
  cx: number,
  cy: number,
  color: string,
  size = 40,
): string {
  const r = size / 2;
  const s = size * 0.45;
  const ox = cx - s / 2;
  const oy = cy - s / 2;

  let glyph = "";
  if (kind === "challenge") {
    glyph = `<path d="M${cx} ${cy - s * 0.4} L${cx + s * 0.35} ${cy + s * 0.35} H${cx - s * 0.35} Z" fill="white"/>`;
  } else if (kind === "impact") {
    glyph = `<rect x="${ox}" y="${oy + s * 0.5}" width="${s * 0.22}" height="${s * 0.45}" fill="white"/><rect x="${ox + s * 0.28}" y="${oy + s * 0.25}" width="${s * 0.22}" height="${s * 0.7}" fill="white"/><rect x="${ox + s * 0.56}" y="${oy}" width="${s * 0.22}" height="${s * 0.95}" fill="white"/>`;
  } else if (kind === "solution") {
    glyph = `<path d="M${cx - s * 0.35} ${cy} L${cx - s * 0.05} ${cy + s * 0.28} L${cx + s * 0.38} ${cy - s * 0.32}" fill="none" stroke="white" stroke-width="${Math.max(3, size * 0.08)}" stroke-linecap="round"/>`;
  } else if (kind === "service") {
    if (vertical === "sms") {
      glyph = `<rect x="${ox + s * 0.15}" y="${oy}" width="${s * 0.7}" height="${s * 0.95}" rx="${s * 0.12}" fill="none" stroke="white" stroke-width="3"/><rect x="${ox + s * 0.28}" y="${oy + s * 0.22}" width="${s * 0.44}" height="${s * 0.12}" rx="2" fill="white"/>`;
    } else if (vertical === "fax") {
      glyph = `<rect x="${ox}" y="${oy + s * 0.15}" width="${s * 0.75}" height="${s * 0.7}" rx="3" fill="none" stroke="white" stroke-width="3"/><path d="M${ox + s * 0.15} ${oy + s * 0.35} H${ox + s * 0.6}" stroke="white" stroke-width="2"/>`;
    } else if (vertical === "email") {
      glyph = `<path d="M${ox} ${oy + s * 0.2} L${cx} ${oy + s * 0.55} L${ox + s} ${oy + s * 0.2} Z" fill="none" stroke="white" stroke-width="3"/><rect x="${ox}" y="${oy + s * 0.2}" width="${s}" height="${s * 0.65}" rx="2" fill="none" stroke="white" stroke-width="3"/>`;
    } else {
      glyph = `<circle cx="${cx}" cy="${cy}" r="${s * 0.32}" fill="none" stroke="white" stroke-width="3"/><circle cx="${cx}" cy="${cy}" r="${s * 0.12}" fill="white"/>`;
    }
  } else {
    glyph = `<path d="M${cx} ${cy + s * 0.35} C${cx} ${cy - s * 0.1} ${cx - s * 0.35} ${cy - s * 0.35} ${cx - s * 0.35} ${cy - s * 0.05} C${cx - s * 0.35} ${cy + s * 0.15} ${cx} ${cy + s * 0.35} ${cx} ${cy + s * 0.35} C${cx} ${cy + s * 0.35} ${cx + s * 0.35} ${cy + s * 0.15} ${cx + s * 0.35} ${cy - s * 0.05} C${cx + s * 0.35} ${cy - s * 0.35} ${cx} ${cy - s * 0.1} ${cx} ${cy + s * 0.35} Z" fill="white"/>`;
  }

  return `
  <circle cx="${cx}" cy="${cy}" r="${r + 8}" fill="${color}" opacity="0.15"/>
  <circle cx="${cx}" cy="${cy}" r="${r}" fill="${color}"/>
  ${glyph}`;
}

export function buildVerticalProductPanel(
  ctx: SocialImageContext,
  box: { x: number; y: number; width: number; height: number },
): string {
  const { primaryColor, accentColor, vertical } = ctx.brandStyle;
  const { x, y, width, height } = box;
  const labelLines = wrapText(ctx.brandStyle.primaryService, 22, 1);
  const subLines = wrapText(ctx.brandStyle.tagline, 32, 2);

  const base = `
  <rect x="${x}" y="${y}" width="${width}" height="${height}" rx="24" fill="url(#photoGrad)"/>
  <rect x="${x + 24}" y="${y + 24}" width="${width - 48}" height="${height - 48}" rx="16" fill="white" opacity="0.92"/>`;

  let illustration = "";
  if (vertical === "sms") {
    illustration = `
  <rect x="${x + width / 2 - 55}" y="${y + 80}" width="110" height="200" rx="18" fill="${primaryColor}" opacity="0.12" stroke="${primaryColor}" stroke-width="2"/>
  <rect x="${x + width / 2 - 40}" y="${y + 110}" width="80" height="28" rx="10" fill="${accentColor}" opacity="0.85"/>
  <rect x="${x + width / 2 - 40}" y="${y + 150}" width="70" height="28" rx="10" fill="${primaryColor}" opacity="0.2"/>
  <rect x="${x + width / 2 - 40}" y="${y + 190}" width="75" height="28" rx="10" fill="${accentColor}" opacity="0.65"/>`;
  } else if (vertical === "fax") {
    illustration = `
  <rect x="${x + 80}" y="${y + 100}" width="200" height="140" rx="10" fill="white" stroke="${primaryColor}" stroke-width="2"/>
  <rect x="${x + 100}" y="${y + 125}" width="55" height="70" rx="4" fill="${accentColor}" opacity="0.85"/>`;
  } else {
    illustration = `
  <rect x="${x + 80}" y="${y + 100}" width="${width - 160}" height="120" rx="10" fill="white" stroke="${primaryColor}" stroke-width="2"/>`;
  }

  const captionY = y + height - 120;
  return `${base}${illustration}
  <rect x="${x + 40}" y="${captionY}" width="${width - 80}" height="88" rx="12" fill="${primaryColor}"/>
  ${multilineTextSvg(x + width / 2, captionY + 32, labelLines.map((l) => l.toUpperCase()), {
    fontSize: 20,
    fontWeight: "bold",
    fill: "white",
    lineHeight: 24,
    anchor: "middle",
  })}
  ${multilineTextSvg(x + width / 2, captionY + 56, subLines, {
    fontSize: 16,
    fill: accentColor,
    lineHeight: 20,
    anchor: "middle",
  })}`;
}

export function buildFooterBenefitsRow(
  benefits: string[],
  primaryColor: string,
  canvasWidth = 1080,
): string {
  const icons = ["$", "⏱", "🛡", "📈"];
  const items = benefits.slice(0, 4);
  if (!items.length) return "";
  const slot = canvasWidth / Math.max(items.length, 1);
  return items
    .map((benefit, i) => {
      const x = slot * i + slot / 2;
      const icon = icons[i] ?? "•";
      return `<text x="${x}" y="954" text-anchor="middle" fill="white" font-family="Arial,sans-serif" font-size="13" font-weight="700">${icon} ${escapeXml(benefit.slice(0, 22))}</text>`;
    })
    .join("");
}

/** Lifestyle photo zone + product infographic overlay (reference poster style). */
function buildProductInfographic(
  cx: number,
  cy: number,
  vertical: BrandVertical,
  primaryColor: string,
  accentColor: string,
  serviceLabel = "DOC",
): string {
  if (vertical === "fax") {
    const label = serviceLabel.slice(0, 8).toUpperCase() || "DOC";
    return `
  <ellipse cx="${cx}" cy="${cy - 40}" rx="72" ry="44" fill="white" stroke="${primaryColor}" stroke-width="2.5"/>
  <text x="${cx}" y="${cy - 34}" text-anchor="middle" fill="${primaryColor}" font-family="Arial,sans-serif" font-size="14" font-weight="bold">${escapeXml(label)}</text>
  <line x1="${cx}" y1="${cy + 4}" x2="${cx - 70}" y2="${cy + 70}" stroke="${primaryColor}" stroke-width="2" stroke-dasharray="6 4"/>
  <line x1="${cx}" y1="${cy + 4}" x2="${cx + 70}" y2="${cy + 70}" stroke="${primaryColor}" stroke-width="2" stroke-dasharray="6 4"/>
  <rect x="${cx - 95}" y="${cy + 58}" width="50" height="34" rx="4" fill="white" stroke="${primaryColor}" stroke-width="2"/>
  <rect x="${cx + 45}" y="${cy + 52}" width="28" height="48" rx="6" fill="white" stroke="${primaryColor}" stroke-width="2"/>
  <circle cx="${cx}" cy="${cy + 20}" r="18" fill="${accentColor}"/>
  <path d="M${cx - 8} ${cy + 20} L${cx - 1} ${cy + 27} L${cx + 10} ${cy + 14}" fill="none" stroke="white" stroke-width="3" stroke-linecap="round"/>`;
  }
  if (vertical === "sms") {
    return `
  <rect x="${cx - 40}" y="${cy - 50}" width="80" height="100" rx="12" fill="white" stroke="${primaryColor}" stroke-width="2"/>
  <rect x="${cx - 28}" y="${cy - 30}" width="56" height="22" rx="8" fill="${accentColor}" opacity="0.9"/>
  <rect x="${cx - 28}" y="${cy}" width="48" height="22" rx="8" fill="${primaryColor}" opacity="0.2"/>
  <circle cx="${cx + 60}" cy="${cy + 10}" r="16" fill="${accentColor}"/>
  <path d="M${cx + 53} ${cy + 10} L${cx + 58} ${cy + 15} L${cx + 68} ${cy + 5}" fill="none" stroke="white" stroke-width="2.5"/>`;
  }
  if (vertical === "email") {
    return `
  <rect x="${cx - 55}" y="${cy - 35}" width="110" height="70" rx="6" fill="white" stroke="${primaryColor}" stroke-width="2"/>
  <path d="M${cx - 45} ${cy - 20} L${cx} ${cy + 10} L${cx + 45} ${cy - 20}" fill="none" stroke="${accentColor}" stroke-width="2.5"/>
  <circle cx="${cx}" cy="${cy + 45}" r="16" fill="${accentColor}"/>
  <path d="M${cx - 7} ${cy + 45} L${cx - 1} ${cy + 51} L${cx + 9} ${cy + 39}" fill="none" stroke="white" stroke-width="2.5"/>`;
  }
  return `
  <rect x="${cx - 50}" y="${cy - 30}" width="100" height="60" rx="8" fill="white" stroke="${primaryColor}" stroke-width="2"/>
  <circle cx="${cx}" cy="${cy + 40}" r="16" fill="${accentColor}"/>
  <path d="M${cx - 7} ${cy + 40} L${cx - 1} ${cy + 46} L${cx + 9} ${cy + 34}" fill="none" stroke="white" stroke-width="2.5"/>`;
}

export function buildPhotoHeroPanel(
  ctx: SocialImageContext,
  box: { x: number; y: number; width: number; height: number },
): string {
  const { primaryColor, accentColor } = ctx.brandStyle;
  const { x, y, width, height } = box;
  const cx = x + width / 2;
  const cy = y + height / 2 + 20;
  const clipId = `photoClip${(ctx.layoutSeed ?? 0) % 9973}`;

  // Prefer disk path for FFmpeg (data-URLs in SVG often fail to rasterize).
  let imageHref: string | null = null;
  if (ctx.heroImageFilePath?.trim()) {
    const normalized = ctx.heroImageFilePath.replace(/\\/g, "/");
    imageHref = normalized.match(/^[A-Za-z]:\//)
      ? `file:///${normalized}`
      : normalized.startsWith("file:")
        ? normalized
        : `file://${normalized}`;
  } else if (ctx.heroImageDataUrl?.startsWith("data:image")) {
    imageHref = ctx.heroImageDataUrl.replace(/"/g, "&quot;");
  }

  if (imageHref) {
    return `
  <defs>
    <clipPath id="${clipId}">
      <rect x="${x}" y="${y}" width="${width}" height="${height}" rx="16"/>
    </clipPath>
    <linearGradient id="heroFade${clipId}" x1="0%" y1="0%" x2="0%" y2="100%">
      <stop offset="0%" style="stop-color:#000;stop-opacity:0"/>
      <stop offset="100%" style="stop-color:#000;stop-opacity:0.28"/>
    </linearGradient>
  </defs>
  <rect x="${x}" y="${y}" width="${width}" height="${height}" rx="16" fill="#0f172a"/>
  <g clip-path="url(#${clipId})">
    <image href="${imageHref}" xlink:href="${imageHref}" x="${x}" y="${y}" width="${width}" height="${height}" preserveAspectRatio="xMidYMid slice"/>
    <rect x="${x}" y="${y}" width="${width}" height="${height}" fill="url(#heroFade${clipId})"/>
  </g>
  <rect x="${x}" y="${y}" width="${width}" height="${height}" rx="16" fill="none" stroke="${primaryColor}" stroke-opacity="0.18" stroke-width="2"/>
  <rect x="${x + 16}" y="${y + height - 48}" width="120" height="8" rx="4" fill="${accentColor}" opacity="0.85"/>`;
  }

  // Fallback: product storytelling graphics (not a generic headshot silhouette).
  const service = ctx.brandStyle.primaryService || ctx.brandStyle.solutionCategory || "OPS";
  const info = buildProductInfographic(cx, cy - 20, ctx.brandStyle.vertical, primaryColor, accentColor, service);
  return `
  <defs>
    <clipPath id="${clipId}">
      <rect x="${x}" y="${y}" width="${width}" height="${height}" rx="14"/>
    </clipPath>
  </defs>
  <rect x="${x}" y="${y}" width="${width}" height="${height}" rx="14" fill="#0f172a"/>
  <rect x="${x}" y="${y}" width="${width}" height="${height}" rx="14" fill="url(#photoGrad)" opacity="0.55"/>
  <g clip-path="url(#${clipId})">
    <circle cx="${cx + 80}" cy="${cy - 90}" r="70" fill="${primaryColor}" opacity="0.25"/>
    <circle cx="${cx - 90}" cy="${cy + 100}" r="90" fill="${accentColor}" opacity="0.18"/>
    ${info}
  </g>
  <rect x="${x}" y="${y}" width="${width}" height="${height}" rx="14" fill="none" stroke="${primaryColor}" stroke-opacity="0.2" stroke-width="2"/>`;
}

export function buildRightPanelCta(ctx: SocialImageContext, box: { x: number; y: number; width: number; height: number }): string {
  const { primaryColor, accentColor } = ctx.brandStyle;
  const { x, y, width, height } = box;
  const ctaLines = wrapText(ctx.brandStyle.ctaLine, 32, 2);
  const subLines = wrapText(ctx.brandStyle.ctaSubline, 32, 1);

  return `
  <rect x="${x}" y="${y}" width="${width}" height="${height}" rx="10" fill="${primaryColor}"/>
  <rect x="${x + 16}" y="${y + 18}" width="36" height="36" rx="6" fill="${accentColor}" opacity="0.9"/>
  <path d="M${x + 28} ${y + 38} L${x + 28} ${y + 48} M${x + 23} ${y + 43} L${x + 33} ${y + 43}" stroke="white" stroke-width="2.5" stroke-linecap="round"/>
  ${multilineTextSvg(x + 64, y + 32, ctaLines, { fontSize: 12, fontWeight: "bold", fill: "white", lineHeight: 15 })}
  ${multilineTextSvg(x + 64, y + 32 + ctaLines.length * 15 + 4, subLines, { fontSize: 11, fontWeight: "bold", fill: accentColor, lineHeight: 14 })}`;
}

export function buildRightPanelVisual(
  ctx: SocialImageContext,
  box?: { x: number; y: number; width: number; height: number },
): string {
  const px = box?.x ?? 560;
  const py = box?.y ?? 150;
  const pw = box?.width ?? 480;
  const photoH = box?.height ?? 520;
  return buildPhotoHeroPanel(ctx, { x: px, y: py, width: pw, height: photoH });
}

