import React, { useEffect, useMemo, useRef, useState } from "react";
import { useParams } from "wouter";
import { ArrowLeft, Download } from "lucide-react";
import { Link } from "wouter";
import { DashboardTemplatePage } from "@/components/DashboardTemplatePage";
import type { LogoTemplate as FirebaseLogoDoc } from "../types/logo-types";

// --- helpers ---------------------------------------------------------------

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();
}

function ensureSvgRoot(svgString: string): string {
  if (!svgString) return "";
  let s = svgString.trim();
  s = s.replace(/^\s*<\?xml[^>]*>\s*/i, "");
  s = s.replace(/<!DOCTYPE[^>]*>/gi, "");
  if (!/<svg[\s>]/i.test(s)) {
    s = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 512">${s}</svg>`;
  }
  s = s.replace(
    /<svg\b(?![^>]*\sxmlns=)/i,
    `<svg xmlns="http://www.w3.org/2000/svg"`
  );
  if (!/viewBox="/i.test(s)) {
    s = s.replace(/<svg\b([^>]*)>/i, `<svg$1 viewBox="0 0 1024 512">`);
  }
  if (!/role="/i.test(s)) {
    s = s.replace(/<svg\b([^>]*)>/i, `<svg$1 role="img" aria-label="Logo">`);
  }
  return s;
}

// quick arc path
const buildArcPath = (x: number, y: number, width: number, curve: number) => {
  const x0 = x - width / 2;
  const x1 = x + width / 2;
  const arcFlag = curve > 0 ? 0 : 1;
  const rx = Math.abs(curve) + width / 2;
  return `M ${x0},${y} A ${rx},${rx} 0 0,${arcFlag} ${x1},${y}`;
};

// --- component -------------------------------------------------------------

export default function LogoCustomizerPage() {
  const { id } = useParams<{ id: string }>();

  // template
  const [template, setTemplate] = useState<{
    id: string;
    name: string;
    svg: string; // raw svg (may be empty if cors blocked)
    previewUrl?: string;
    defaultFields?: { Brand_Name?: string; Tagline?: string; Est_Year?: string };
    fieldOrder?: string[];
    defaultColors?: { primary: string; secondary?: string; accent?: string };
  } | null>(null);

  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // form state
  const [brandName, setBrandName] = useState("Your Brand");
  const [tagline, setTagline] = useState("Your Tagline");
  const [estYear, setEstYear] = useState("2025");
  const [colors, setColors] = useState<{ primary: string; secondary: string; accent: string }>({
    primary: "#231f20",
    secondary: "#978752",
    accent: "#6dc282",
  });

  // transforms
  const [brandNameSize, setBrandNameSize] = useState(100);
  const [taglineSize, setTaglineSize] = useState(100);
  const [estYearSize, setEstYearSize] = useState(100);

  const [textPositions, setTextPositions] = useState<Record<string, { x: number; y: number }>>({});
  const [textShapes, setTextShapes] = useState<Record<string, { rotation: number; curve: number }>>({
    "brand-name": { rotation: 0, curve: 0 },
    "tagline": { rotation: 0, curve: 0 },
    "est-year": { rotation: 0, curve: 0 },
  });
  const [dragId, setDragId] = useState<string | null>(null);
  const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });

  const previewRef = useRef<HTMLDivElement | null>(null);

  // load template (firebase → proxy → manifest)
  useEffect(() => {
    if (!id) return;

    const load = async () => {
      setLoading(true);
      setError(null);

      // local util: fetch text (with friendlier errors)
      const fetchText = async (u: string) => {
        try {
          const r = await fetch(u, { cache: "no-store" });
          if (!r.ok) throw new Error(`HTTP ${r.status}`);
          return await r.text();
        } catch (e: any) {
          throw new Error(`Failed to fetch ${u.split("?")[0]} (${e?.message || "network"})`);
        }
      };

      try {
        // 1) try firebase
        try {
          const svc = await import("@/services/firebase-templates");
          let fb: any = null;

          try { fb = await svc.getTemplateById(id); } catch {}
          if (!fb && id.startsWith("logo-wordmark-")) {
            try { fb = await svc.getTemplateById(id.replace("logo-wordmark-", "")); } catch {}
          }

          if (fb) {
            const out = {
              id: fb.id,
              name: fb.name || id,
              svg: "",
              previewUrl: fb.assets?.previewDownloadUrl,
              defaultFields: {
                Brand_Name: fb.defaults?.brandName || "Your Brand",
                Tagline: fb.defaults?.tagline || "Your Tagline",
                Est_Year: fb.defaults?.estYear || "2025",
              },
              fieldOrder: ["Brand_Name", "Tagline", "Est_Year"],
              defaultColors: { primary: "#231f20", secondary: "#978752", accent: "#6dc282" },
            };

            // a) direct doc (preferred)
            try {
              const detail = await svc.readDoc("logo_templates", fb.id);
              if (detail?.svg) out.svg = detail.svg;
            } catch {}

            // b) proxy (cors-safe)
            if (!out.svg && fb.assets?.svgDownloadUrl) {
              try {
                const prox = `/api/firebase-proxy?url=${encodeURIComponent(fb.assets.svgDownloadUrl)}`;
                out.svg = await fetchText(prox);
              } catch {}
            }

            // finalize
            out.svg = ensureSvgRoot(out.svg);
            setTemplate(out);
            setBrandName(out.defaultFields!.Brand_Name!);
            setTagline(out.defaultFields!.Tagline!);
            setEstYear(out.defaultFields!.Est_Year!);
            setColors(out.defaultColors!);
            setLoading(false);
            return;
          }
        } catch (_) {
          // ignore, fall through to manifest
        }

        // 2) manifest fallback
        const manRes = await fetch("/site/data/manifest.logo.json", { cache: "no-cache" });
        if (!manRes.ok) throw new Error("Failed to load template manifest");
        const manifest = await manRes.json();
        const item = manifest.items?.find((x: any) => x.id === id);
        if (!item) throw new Error(`Template ${id} not found`);

        let svg = "";
        try {
          svg = await fetchText(item.svgUrl);
        } catch (e) {
          // leave blank; we will show previewUrl instead
        }

        const out = {
          id: item.id,
          name: item.name || id,
          svg: ensureSvgRoot(svg),
          previewUrl: item.previewUrl,
          defaultFields: item.defaultFields || { Brand_Name: "Your Brand", Tagline: "Your Tagline", Est_Year: "2025" },
          fieldOrder: item.fieldOrder || ["Brand_Name", "Tagline", "Est_Year"],
          defaultColors: item.defaultColors || { primary: "#231f20", secondary: "#978752", accent: "#6dc282" },
        };

        setTemplate(out);
        setBrandName(out.defaultFields!.Brand_Name!);
        setTagline(out.defaultFields!.Tagline!);
        setEstYear(out.defaultFields!.Est_Year!);
        setColors(out.defaultColors!);
      } catch (e: any) {
        setError(e?.message || "Failed to load template");
      } finally {
        setLoading(false);
      }
    };

    load();
  }, [id]);

  // build live svg (token replacement + CSS var injection + text transforms)
  const resolvedSvg = useMemo(() => {
    if (!template?.svg) return "";

    // 1) replace tokens
    const vals = {
      Brand_Name: brandName,
      Tagline: tagline,
      Est_Year: estYear,
    };
    let svg = template.svg;
    Object.entries(vals).forEach(([k, v]) => {
      const token = new RegExp(`\\{${escapeRegExp(k)}\\}`, "g");
      svg = svg.replace(token, escapeXml(String(v)));
    });

    // 2) inject colors on root
    svg = svg.replace(
      /<svg([^>]*?)>/,
      `<svg$1 style="--primary:${colors.primary};--secondary:${colors.secondary};--accent:${colors.accent};max-width:100%;height:auto;">`
    );

    // 3) adjust text sizes/positions/curves/rotation by rewriting <text> nodes
    let defs = "";
    svg = svg.replace(/<text([^>]*?)>([\s\S]*?)<\/text>/g, (m, attrs, content) => {
      // decode entities for matching
      const ta = document.createElement("textarea");
      ta.innerHTML = content;
      const decoded = (ta.value || "").trim();

      let idGuess = "";
      let sizePct = 100;
      if (decoded && brandName && (decoded === brandName || brandName.includes(decoded) || decoded.includes(brandName))) {
        idGuess = "brand-name";
        sizePct = brandNameSize;
      } else if (decoded && tagline && (decoded === tagline || tagline.includes(decoded) || decoded.includes(tagline))) {
        idGuess = "tagline";
        sizePct = taglineSize;
      } else if (decoded && estYear && (decoded === estYear || estYear.includes(decoded) || decoded.includes(estYear))) {
        idGuess = "est-year";
        sizePct = estYearSize;
      }

      // base font-size
      const fs = (attrs.match(/font-size="([^"]+)"/)?.[1] ?? "14").trim();
      const base = parseFloat(fs) || 14;
      const scaled = base * (sizePct / 100);

      // base position
      let x = parseFloat(attrs.match(/x="([^"]+)"/)?.[1] ?? "0");
      let y = parseFloat(attrs.match(/y="([^"]+)"/)?.[1] ?? "0");

      if (idGuess && textPositions[idGuess]) {
        x = textPositions[idGuess].x;
        y = textPositions[idGuess].y;
      }

      const shape = idGuess ? textShapes[idGuess] : { rotation: 0, curve: 0 };
      let newAttrs = attrs
        .replace(/\s*font-size="[^"]*"/g, "")
        .replace(/\s*x="[^"]*"/g, "")
        .replace(/\s*y="[^"]*"/g, "")
        .replace(/\s*transform="[^"]*"/g, "")
        .replace(/\s*id="[^"]*"/g, "");

      if (shape?.curve) {
        const textWidth = decoded.length * scaled * 0.6;
        const arcId = `arc-${idGuess || "txt"}-${Math.random().toString(36).slice(2, 7)}`;
        defs += `<path id="${arcId}" d="${buildArcPath(x, y, textWidth, shape.curve)}" />`;
        newAttrs += ` id="${idGuess}" x="${x}" y="${y}" font-size="${scaled}" style="cursor:move;user-select:none"`;
        return `<text${newAttrs}><textPath href="#${arcId}" startOffset="50%" text-anchor="middle">${content}</textPath></text>`;
      } else {
        const rot = shape?.rotation || 0;
        const transform = rot ? ` transform="rotate(${rot} ${x} ${y})"` : "";
        newAttrs += ` id="${idGuess}" x="${x}" y="${y}" font-size="${scaled}" style="cursor:move;user-select:none"`;
        return `<text${newAttrs}${transform}>${content}</text>`;
      }
    });

    if (defs) {
      svg = svg.replace(/(<svg[^>]*>)/, `$1<defs>${defs}</defs>`);
    }
    return svg;
  }, [template, brandName, tagline, estYear, colors, brandNameSize, taglineSize, estYearSize, textPositions, textShapes]);

  // drag handlers on the injected SVG
  useEffect(() => {
    const containe
