import { MemberCardData, CardTemplateConfig, ExportFormat } from "@/templates/membership-card/types"
import config from "@/templates/membership-card/config.json"
import { generateQRDataURL } from "./qrCode"

const templateConfig = config as CardTemplateConfig

export interface RenderOptions {
  lang?: string
  origin?: string
  format?: ExportFormat
}

export interface RenderResult {
  frontHtml: string
  backHtml: string
  png?: string
  pdf?: string
}

class TemplateEngineClass {
  async render(member: MemberCardData, options: RenderOptions = {}): Promise<RenderResult> {
    const lang = options.lang || "ar"
    const origin = options.origin || "http://localhost:9000"

    const qrDataURL = await generateQRDataURL(
      member.qrValue || `${origin}/${lang}/verify?id=${member.membershipNumber}`
    )

    const isRtl = lang === "ar"

    const frontHtml = this.buildFrontHtml(member, qrDataURL, isRtl)
    const backHtml = this.buildBackHtml(member, isRtl)

    return { frontHtml, backHtml }
  }

  private buildFrontHtml(member: MemberCardData, qrDataURL: string, isRtl: boolean): string {
    const c = templateConfig.front.elements
    const card = templateConfig.card

    const photoStyle = this.elementStyle(c.photo)
    const nameArStyle = this.elementStyle(c.nameAr)
    const nameEnStyle = this.elementStyle(c.nameEn)
    const memberNoStyle = this.elementStyle(c.membershipNumber)
    const specializationStyle = this.elementStyle(c.specialization)
    const gradYearStyle = this.elementStyle(c.graduationYear)
    const qrStyle = this.elementStyle(c.qrCode)

    return `
<div style="position:relative;width:${card.widthMm}mm;height:${card.heightMm}mm;overflow:hidden;border-radius:4px;background:url('${templateConfig.front.background}') no-repeat center/cover;">
  ${member.photo ? `<img src="${member.photo}" alt="" style="position:absolute;${photoStyle}object-fit:cover;" />` : ""}
  <div style="position:absolute;${nameArStyle}">${this.escapeHtml(isRtl ? member.nameAr : member.nameEn)}</div>
  <div style="position:absolute;${nameEnStyle}">${this.escapeHtml(isRtl ? member.nameEn : member.nameAr)}</div>
  <div style="position:absolute;${memberNoStyle}">${this.escapeHtml(member.membershipNumber)}</div>
  <div style="position:absolute;${specializationStyle}">${this.escapeHtml(member.specialization || member.department || "")}</div>
  <div style="position:absolute;${gradYearStyle}">${member.graduationYear ? `تخرج ${member.graduationYear}` : ""}</div>
  <img src="${qrDataURL}" alt="QR" style="position:absolute;${qrStyle}" />
</div>`
  }

  private buildBackHtml(member: MemberCardData, isRtl: boolean): string {
    const c = templateConfig.back.elements
    const card = templateConfig.card

    const expiryStyle = this.elementStyle(c.expiryDate)
    const barcodeStyle = this.elementStyle(c.barcode)
    const contactStyle = this.elementStyle(c.contactInfo)

    return `
<div style="position:relative;width:${card.widthMm}mm;height:${card.heightMm}mm;overflow:hidden;border-radius:4px;background:url('${templateConfig.back.background}') no-repeat center/cover;direction:${isRtl ? "rtl" : "ltr"};">
  <div style="position:absolute;${expiryStyle}">${member.expiryDate || "20/05/2028"}</div>
  ${member.barcodeValue ? `<div style="position:absolute;${barcodeStyle}">
    <svg width="100%" height="100%"></svg>
  </div>` : ""}
  <div style="position:absolute;${contactStyle}">
    ${member.email ? `Email: ${member.email}<br/>` : ""}
    ${member.phone ? `Tel: ${member.phone}` : ""}
  </div>
</div>`
  }

  private elementStyle(el: { x: number; y: number; width?: number | string; height?: number | string; fontSize?: number; fontWeight?: string; color?: string; textAlign?: string; fontFamily?: string; lineHeight?: number; borderRadius?: number; border?: string; clipPath?: string; size?: number }): string {
    const parts: string[] = []
    parts.push(`left:${el.x}%;`)
    parts.push(`top:${el.y}%;`)
    if (el.width !== undefined) parts.push(`width:${typeof el.width === "number" ? el.width + "%" : el.width};`)
    if (el.height !== undefined) parts.push(`height:${typeof el.height === "number" ? el.height + "%" : el.height};`)
    if (el.fontSize !== undefined) parts.push(`font-size:${el.fontSize}pt;`)
    if (el.fontWeight !== undefined) parts.push(`font-weight:${el.fontWeight};`)
    if (el.color !== undefined) parts.push(`color:${el.color};`)
    if (el.textAlign !== undefined) parts.push(`text-align:${el.textAlign};`)
    if (el.fontFamily !== undefined) parts.push(`font-family:${el.fontFamily};`)
    if (el.lineHeight !== undefined) parts.push(`line-height:${el.lineHeight};`)
    if (el.borderRadius !== undefined) parts.push(`border-radius:${el.borderRadius}px;`)
    if (el.border !== undefined) parts.push(`border:${el.border};`)
    if (el.clipPath === "circle") parts.push("border-radius:50%;")
    if (el.size !== undefined) {
      parts.push(`width:${el.size}%;`)
      parts.push(`height:auto;`)
    }
    if (!parts.some(p => p.startsWith("width") || p.startsWith("height"))) {
      parts.push("white-space:nowrap;")
    }
    return parts.join("")
  }

  private escapeHtml(text: string): string {
    return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;")
  }
}

export const TemplateEngine = new TemplateEngineClass()
