import React, { useEffect, useMemo, useRef, useState } from "react";
import { LogoTemplate } from "./logo-types";

// Simple modal shell using Headless approach (swap with your shadcn/ui Dialog if you prefer)
export function LogoCustomizerModal({
  open,
  onOpenChange,
  template,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  template?: LogoTemplate;
}) {
  const [fields, setFields] = useState<Record<string, string>>({});
  const [colors, setColors] = useState<{ primary: string; secondary: string; accent: string }>({
    primary: "#231f20",
    secondary: "#978752",
    accent: "#6dc282",
  });

  // Initialize when template changes
  useEffect(() => {
    if (!template) return;
    setFields(template.defaultFields || {});
    setColors(template.defaultColors || colors);
  }, [template]);

  // Build SVG string with tokens replaced and CSS vars injected
  const resolvedSvg = useMemo(() => {
    if (!template) return "";
    let svg = template.svg;

    // Replace text tokens
    Object.entries(fields).forEach(([key, val]) => {
      const token = new RegExp(`\\{${escapeRegExp(key)}\\}`, "g");
      svg = svg.replace(token, escapeXml(val));
    });

    // Ensure CSS vars are set on root <svg>
    svg = svg.replace(
      /<svg([^>]*?)>/,
      `<svg$1 style="--primary:${colors.primary};--secondary:${colors.secondary};--accent:${colors.accent};">`
    );

    return svg;
  }, [template, fields, colors]);

  // Render preview via dangerouslySetInnerHTML into a sandboxed wrapper
  const previewRef = useRef<HTMLDivElement>(null);

  // Download SVG
  const downloadSVG = () => {
    if (!resolvedSvg) return;
    const blob = new Blob([resolvedSvg], { type: "image/svg+xml;charset=utf-8" });
    const url = URL.createObjectURL(blob);
    triggerDownload(url, `${template?.id || "logo"}.svg`);
    URL.revokeObjectURL(url);
  };

  // Download PNG using an offscreen canvas
  const downloadPNG = async (px = 2000) => {
    if (!resolvedSvg) return;
    const svgBlob = new Blob([resolvedSvg], { type: "image/svg+xml;charset=utf-8" });
    const url = URL.createObjectURL(svgBlob);
    const img = new Image();
    img.decoding = "async";
    img.onload = () => {
      const canvas = document.createElement("canvas");
      const ratio = img.width ? px / img.width : 1;
      canvas.width = px;
      canvas.height = Math.round(img.height * ratio);
      const ctx = canvas.getContext("2d");
      if (!ctx) return;
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
      canvas.toBlob((blob) => {
        if (!blob) return;
        const out = URL.createObjectURL(blob);
        triggerDownload(out, `${template?.id || "logo"}@${px}px.png`);
        URL.revokeObjectURL(out);
        URL.revokeObjectURL(url);
      }, "image/png");
    };
    img.onerror = () => URL.revokeObjectURL(url);
    img.src = url;
  };

  if (!open || !template) return null;

  const orderedFields = template.fieldOrder?.length
    ? template.fieldOrder
    : Object.keys(fields);

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4">
      <div className="w-full max-w-6xl rounded-2xl bg-white shadow-xl overflow-hidden grid md:grid-cols-[1.2fr_1fr]">
        {/* Preview */}
        <div className="p-6 bg-gray-50">
          <div className="mb-3 text-sm text-gray-600">Live Preview</div>
          <div
            ref={previewRef}
            className="w-full bg-white rounded-xl border overflow-auto flex items-center justify-center"
            style={{ minHeight: 420, maxHeight: 600 }}
            dangerouslySetInnerHTML={{ __html: resolvedSvg }}
          />
        </div>

        {/* Controls */}
        <div className="p-6">
          <div className="text-lg font-semibold mb-4">{template.name}</div>

          <div className="space-y-4">
            {orderedFields.map((f) => (
              <div key={f} className="grid gap-1">
                <label className="text-xs text-gray-600">{f}</label>
                <input
                  className="rounded-lg border px-3 py-2 text-sm"
                  value={fields[f] || ""}
                  onChange={(e) => setFields((s) => ({ ...s, [f]: e.target.value }))}
                  placeholder={`Enter ${f}`}
                />
              </div>
            ))}

            <div className="grid grid-cols-3 gap-4">
              <ColorPicker
                label="Primary"
                value={colors.primary}
                onChange={(v) => setColors((s) => ({ ...s, primary: v }))}
              />
              <ColorPicker
                label="Secondary"
                value={colors.secondary}
                onChange={(v) => setColors((s) => ({ ...s, secondary: v }))}
              />
              <ColorPicker
                label="Accent"
                value={colors.accent}
                onChange={(v) => setColors((s) => ({ ...s, accent: v }))}
              />
            </div>
          </div>

          {/* Actions */}
          <div className="mt-6 flex flex-wrap gap-3">
            <button
              className="rounded-xl px-4 py-2 border hover:bg-gray-50"
              onClick={() => downloadPNG(2000)}
              title="PNG @ 2000px"
            >
              Download PNG
            </button>
            <button
              className="rounded-xl px-4 py-2 border hover:bg-gray-50"
              onClick={downloadSVG}
              title="Vector SVG"
            >
              Download SVG
            </button>
            <button
              className="rounded-xl px-4 py-2 border hover:bg-gray-50"
              onClick={() => onOpenChange(false)}
            >
              Close
            </button>
          </div>

          <p className="mt-4 text-xs text-gray-500">
            Tip: Keep your master templates as clean SVG with tokens
            {' '}<code>{`{Brand_Name} {Tagline} {Est_Year}`}</code> and colors using
            {' '}<code>var(--primary/secondary/accent)</code>.
          </p>
        </div>
      </div>
    </div>
  );
}

function ColorPicker({
  label,
  value,
  onChange,
}: {
  label: string;
  value: string;
  onChange: (v: string) => void;
}) {
  return (
    <div className="grid gap-1">
      <label className="text-xs text-gray-600">{label}</label>
      <input
        type="color"
        className="h-10 w-full rounded-lg border"
        value={value}
        onChange={(e) => onChange(e.target.value)}
      />
      <input
        className="rounded-lg border px-3 py-2 text-xs"
        value={value}
        onChange={(e) => onChange(e.target.value)}
      />
    </div>
  );
}

function escapeRegExp(s: string) {
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function escapeXml(unsafe: string) {
  return unsafe
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#039;");
}
function triggerDownload(url: string, filename: string) {
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  a.remove();
}
