import sharp from "sharp";
import { escapeXml, DEFAULT_UI_FONT } from "@/lib/generation/brand-svg-shared";

/**
 * Image models reliably garble phone numbers, emails, and URLs — observed
 * "+91-835577737" and "contact@gvente.ure.net" from correct source values.
 *
 * The banner prompt therefore reserves a clean band at the bottom of the
 * canvas, and the exact contact details are stamped here in code. Same
 * principle as the logo overlay: creative from the model, facts from us.
 */

/** Fraction of canvas height reserved for the stamped strip. */
export const CONTACT_STRIP_RATIO = 0.104;

export interface ContactStripInput {
  phone?: string | null;
  email?: string | null;
  website?: string | null;
  primaryColor: string;
  accentColor: string;
}

export function hasContactStripContent(input: ContactStripInput): boolean {
  return Boolean(input.phone?.trim() || input.email?.trim() || input.website?.trim());
}

function phoneIcon(cx: number, cy: number, color: string): string {
  const s = 9;
  return `<path d="M${cx - s} ${cy - s} q0 -3 3 -3 l3 0 q2 0 2.5 2 l1 4 q0.4 1.7 -1 2.6 l-1.6 1 q1.8 3.6 5 5.4 l1 -1.6 q0.9 -1.4 2.6 -1 l4 1 q2 0.5 2 2.5 l0 3 q0 3 -3 3 q-11 0 -18.5 -7.5 q-1 -1 -1 -11.4 z" fill="${color}"/>`;
}

function mailIcon(cx: number, cy: number, color: string): string {
  const w = 20;
  const h = 14;
  return `<rect x="${cx - w / 2}" y="${cy - h / 2}" width="${w}" height="${h}" rx="2.5" fill="none" stroke="${color}" stroke-width="2"/><path d="M${cx - w / 2 + 1.5} ${cy - h / 2 + 2} L${cx} ${cy + 2} L${cx + w / 2 - 1.5} ${cy - h / 2 + 2}" fill="none" stroke="${color}" stroke-width="2" stroke-linejoin="round"/>`;
}

function globeIcon(cx: number, cy: number, color: string): string {
  const r = 9;
  return `<circle cx="${cx}" cy="${cy}" r="${r}" fill="none" stroke="${color}" stroke-width="2"/><ellipse cx="${cx}" cy="${cy}" rx="${r * 0.45}" ry="${r}" fill="none" stroke="${color}" stroke-width="1.6"/><path d="M${cx - r} ${cy} H${cx + r}" stroke="${color}" stroke-width="1.6"/>`;
}

/** Build the strip SVG sized to the target canvas. */
export function buildContactStripSvg(
  width: number,
  height: number,
  input: ContactStripInput,
): string {
  const phone = input.phone?.trim() || "";
  const email = input.email?.trim() || "";
  const website = (input.website || "").replace(/^https?:\/\//i, "").replace(/\/$/, "");

  const items: Array<{ icon: (cx: number, cy: number, c: string) => string; text: string }> = [];
  if (phone) items.push({ icon: phoneIcon, text: phone });
  if (email) items.push({ icon: mailIcon, text: email });
  if (website) items.push({ icon: globeIcon, text: website });
  if (!items.length) return "";

  const cy = height / 2;
  const fontSize = Math.round(height * 0.3);
  // Approximate the rendered run so icon + label groups stay evenly distributed.
  const widths = items.map((it) => 30 + it.text.length * fontSize * 0.52);
  const totalWidth = widths.reduce((a, b) => a + b, 0);
  const gap = Math.max(24, (width - totalWidth) / (items.length + 1));

  let cursor = gap;
  const groups = items
    .map((item, i) => {
      const iconCx = cursor + 12;
      const textX = cursor + 32;
      const svg = `${item.icon(iconCx, cy, input.accentColor)}<text x="${textX}" y="${cy + fontSize * 0.36}" fill="#ffffff" font-family="${DEFAULT_UI_FONT}" font-size="${fontSize}" font-weight="600">${escapeXml(item.text)}</text>`;
      cursor += widths[i]! + gap;
      return svg;
    })
    .join("");

  return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}">
  <rect width="${width}" height="${height}" fill="${input.primaryColor}"/>
  <rect width="${width}" height="3" fill="${input.accentColor}"/>
  ${groups}
</svg>`;
}

/**
 * Stamp the exact contact details across the reserved bottom band.
 * Returns the original buffer unchanged if there is nothing to stamp.
 */
export async function applyContactStripToBuffer(
  imageBuffer: Buffer,
  input: ContactStripInput,
): Promise<Buffer> {
  if (!hasContactStripContent(input)) return imageBuffer;

  try {
    const meta = await sharp(imageBuffer).metadata();
    const width = meta.width ?? 1024;
    const height = meta.height ?? 1024;
    const stripHeight = Math.round(height * CONTACT_STRIP_RATIO);

    const svg = buildContactStripSvg(width, stripHeight, input);
    if (!svg) return imageBuffer;

    return await sharp(imageBuffer)
      .composite([
        {
          input: Buffer.from(svg),
          top: height - stripHeight,
          left: 0,
        },
      ])
      .png()
      .toBuffer();
  } catch (err) {
    console.warn("[PostSync] Contact strip overlay failed:", err);
    return imageBuffer;
  }
}
