import maplibregl from "maplibre-gl";
import React from "react";
import { createRoot } from "react-dom/client";

const SW_ANIM_MS = 840;

import CardRenderer from "../Cards/CardRenderer";
import { cardTokens } from "../../theme/cardTokens";
import { getTemplateSpecForPost, adaptPostToTemplateData } from "./templateSpecs";

export function clearAllMarkers(markersRef, expandedElRef) {
  if (markersRef.current) {
    for (const m of markersRef.current) {
      try { if (m?.el && m.el.__swUnmount) m.el.__swUnmount(); } catch {}
      try { m.marker.remove(); } catch {}
    }
  }
  markersRef.current = [];
  if (expandedElRef) expandedElRef.current = null;
}

export function applyOcclusionForExpanded() {}
export function clearOcclusion(markersRef) {
  const list = markersRef.current || [];
  for (const item of list) {
    const el = item?.el;
    if (!el) continue;
    el.style.visibility = "visible";
    el.style.pointerEvents = "auto";
  }
}

function mountCard(container, spec, data, theme) {
  const root = createRoot(container);
  const tokens = cardTokens?.[theme] || cardTokens.blue;

  root.render(
    React.createElement(CardRenderer, {
      spec,
      data,
      themeTokens: tokens,
      onAction: (action, value) => {
        if (action?.type === "open_url" && value) {
          try { window.open(value, "_blank"); } catch {}
        }
      },
      className: "",
    })
  );

  return () => {
    try { root.unmount(); } catch {}
  };
}

function escapeHtml(str) {
  return String(str ?? "")
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;");
}

function normCatLabel(post) {
  const c = (post?.category || "").toString().toUpperCase();
  if (c === "NEWS") return "NEWS";
  if (c === "EVENT" || c === "EVENTS") return "EVENTS";
  if (c === "FRIENDS") return "FRIENDS";
  if (c === "MARKET") return "MARKET";
  return "NEWS";
}

function formatRelativeTime(createdAt) {
  try {
    if (!createdAt) return "now";
    const d = createdAt instanceof Date ? createdAt : new Date(String(createdAt));
    if (Number.isNaN(d.getTime())) return "now";

    const s = Math.floor((Date.now() - d.getTime()) / 1000);
    if (s < 60) return "now";
    const m = Math.floor(s / 60);
    if (m < 60) return `${m}m`;
    const h = Math.floor(m / 60);
    if (h < 48) return `${h}h`;
    const days = Math.floor(h / 24);
    return `${days}d`;
  } catch {
    return "now";
  }
}

function closeCenteredOverlay(map) {
  try {
    const ov = map?.__swCenteredOverlay;
    if (!ov) return;
    if (ov.closing) return;

    if (ov.onKey) window.removeEventListener("keydown", ov.onKey);

    // animate out
    try {
      const mw = ov.modalWrapRef;
      if (mw) {
        mw.style.opacity = "0";
        mw.style.transform = "scale(0.96)";
      }
      if (ov.backdrop) ov.backdrop.style.opacity = "0";
    } catch {}
    try { if (ov.unmountFull) ov.unmountFull(); } catch {}
    try { if (ov.unmountMini) ov.unmountMini(); } catch {}
    try {
      const b = ov.backdrop;
      if (b) setTimeout(() => { try { b.remove(); } catch {} }, 300);
    } catch {}

    map.__swCenteredOverlay = null;
  } catch {}
}

function openCenteredOverlay({ map, post, theme }) {
  if (!map) return;

  closeCenteredOverlay(map);

  const data = adaptPostToTemplateData(post);
  const cat = normCatLabel(post);
  const relTime = formatRelativeTime(post?.created_at || post?.CreatedAt || post?.createdAt);
  const author = (post?.author || post?.Author || "").toString().trim();
  const sub = (post?.sub_category || post?.subCategory || "").toString().trim();
  const metaLeft = author ? `by ${author}` : "";
  const metaRight = sub ? sub : "";
  const img = data?.image || "";
  const url = data?.url || "";

  // Backdrop catches outside click to close
  const backdrop = document.createElement("div");
  try { backdrop.classList.add("sw-centered-backdrop","sw-enter"); } catch {}
  backdrop.classList.add("sw-centered-backdrop");
  backdrop.className = "sw-centered-backdrop";
  backdrop.style.position = "fixed";
  backdrop.style.inset = "0";
  backdrop.style.zIndex = "9999999";
  backdrop.style.background = "rgba(0,0,0,0.08)";
  backdrop.style.backdropFilter = "blur(1px)";
  backdrop.style.display = "flex";
  backdrop.style.alignItems = "center";
  backdrop.style.justifyContent = "center";
  backdrop.style.padding = "12px";
  backdrop.style.pointerEvents = "auto";

  // Wrapper uses existing styling hooks
  const modalWrap = document.createElement("div");
  modalWrap.classList.add("sw-centered-modal");
  modalWrap.className = "post-pin--expanded sw-centered-modal";
  modalWrap.style.pointerEvents = "auto";

  // Keep size behavior from your CSS (max-width/min(92vw,...), max-height etc.)
  modalWrap.innerHTML = `
    <div class="post-card sw-expanded-shell sw-modal">
      <div class="sw-modal-toprow">
        <div class="sw-modal-left">
          <div class="sw-modal-badge">${escapeHtml(cat)}</div>
          <div class="sw-modal-meta">
            ${metaLeft ? `<span>${escapeHtml(metaLeft)}</span>` : ""}
            ${metaRight ? `<span>• ${escapeHtml(metaRight)}</span>` : ""}
            <span>• ${escapeHtml(relTime)}</span>
          </div>
        </div>

        <button class="sw-modal-x" type="button" aria-label="Close">✕</button>
      </div>

      <div class="sw-modal-hero">
        ${
          img
            ? `<img src="${escapeHtml(img)}" alt="" loading="lazy" />`
            : `<div class="sw-modal-hero-fallback"></div>`
        }
      </div>

      <div class="sw-modal-title">${escapeHtml(data?.headline || post?.title || "Untitled")}</div>

      <div class="sw-modal-summary">
        ${escapeHtml(data?.summary || post?.snippet || "")}
      </div>

      <div class="sw-stat-row">
        <div class="sw-stat-pill">👁 12.4k</div>
        <div class="sw-stat-pill">❤️ 1.3k</div>
        <div class="sw-stat-pill">💬 248</div>
        <div class="sw-stat-pill">📍 ${escapeHtml(post?.city || post?.location_name || "Nearby")}</div>
      </div>

      <div class="sw-modal-cta-row">
        <button class="sw-cta-primary" type="button" ${url ? "" : "disabled"} data-url="${escapeHtml(url)}">
          Open source
        </button>

        <div class="sw-cta-actions">
          <button class="post-card-btn" type="button">Contact</button>
          <button class="post-card-btn" type="button">Like</button>
          <button class="post-card-btn" type="button">Share</button>
          <button class="post-card-btn" type="button">Fix</button>
        </div>
      </div>

      <div class="post-card-comments sw-livechat">
        <div class="sw-livechat-title">Live chat / comments</div>
        <div class="sw-livechat-body">
          <div class="sw-chat-line">— …</div>
          <div class="sw-chat-line">— what the f***?</div>
          <div class="sw-chat-line">— nice…</div>
          <div class="sw-chat-line">— my eyes!!</div>
        </div>
        <div class="sw-livechat-inputrow">
          <input class="sw-livechat-input" placeholder="Write a comment…" />
          <button class="sw-livechat-post" type="button">POST</button>
        </div>
      </div>

      <!-- (Optional) keep template renderer mounted but hidden for future -->
      <div class="sw-template-full-wrap" style="display:none;"></div>
    </div>
  `;

  backdrop.appendChild(modalWrap);
  document.body.appendChild(backdrop);
  requestAnimationFrame(() => {
    try { backdrop.classList.add("sw-enter-active"); } catch {}
    try { modalWrap.classList.add("sw-enter-active"); } catch {}
  });

  // animate in
  backdrop.style.opacity = "0";
  modalWrap.style.opacity = "0";
  modalWrap.style.transform = "scale(0.96)";
  requestAnimationFrame(() => {
    backdrop.style.transition = "opacity 260ms ease";
    modalWrap.style.transition = "opacity 260ms ease, transform 320ms cubic-bezier(.2,.9,.2,1)";
    backdrop.style.opacity = "1";
    modalWrap.style.opacity = "1";
    modalWrap.style.transform = "scale(1)";
  });


  // ✅ animate in (fade + scale)
  try {
    requestAnimationFrame(() => {
      backdrop.classList.add("sw-open");
      modalWrap.classList.add("sw-open");
    });
  } catch {}

  // outside click closes
  backdrop.addEventListener("click", () => closeCenteredOverlay(map));
  // inside click doesn't close
  modalWrap.addEventListener("click", (e) => e.stopPropagation());

  // close button
  const xbtn = modalWrap.querySelector(".sw-modal-x");
  if (xbtn) xbtn.addEventListener("click", () => closeCenteredOverlay(map));

  // ESC closes
  const onKey = (e) => {
    if (e.key === "Escape") closeCenteredOverlay(map);
  };
  window.addEventListener("keydown", onKey);

  // CTA open url
  const cta = modalWrap.querySelector(".sw-cta-primary");
  if (cta) {
    cta.addEventListener("click", () => {
      const u = cta.getAttribute("data-url") || "";
      if (!u) return;
      try { window.open(u, "_blank", "noopener,noreferrer"); } catch {}
    });
  }

  // still mount template full (hidden) so you can switch back later instantly
  let unmountFull = null;
  const fullWrap = modalWrap.querySelector(".sw-template-full-wrap");
  if (fullWrap) {
    const spec = getTemplateSpecForPost(post, "full");
    unmountFull = mountCard(fullWrap, spec, data, theme);
  }

  map.__swCenteredOverlay = {
    postId: post?.id,
    modalWrapRef: modalWrap,
    backdrop,
    onKey,
    unmountFull,
    unmountMini: null,
  };
}

export function createMarkerForPost(post, mapRef, markersRef, expandedElRef, theme = "blue") {
  const map = mapRef.current;
  if (!map) return;

  const lat =
    typeof post.lat === "number"
      ? post.lat
      : typeof post.latitude === "number"
      ? post.latitude
      : null;

  const lon =
    typeof post.lon === "number"
      ? post.lon
      : typeof post.lng === "number"
      ? post.lng
      : null;

  if (lat == null || lon == null) return;

  const lngLat = [lon, lat];

  const root = document.createElement("div");
  root.classList.add("sw-appear");
  requestAnimationFrame(() => root.classList.add("sw-appear-in"));
  root.className = "post-pin post-pin--compact";
  root.style.zIndex = "1";

  function unmountIfAny() {
    if (root.__swUnmount) {
      try { root.__swUnmount(); } catch {}
      root.__swUnmount = null;
    }
  }

  function renderCompact() {
    unmountIfAny();
    root.className = "post-pin post-pin--compact sw-appear sw-appear-in";
    root.style.zIndex = "1";

    root.innerHTML = `
      <div class="sw-template-mini-wrap"></div>
      <div class="post-pin-pointer-small"></div>
    `;

    const wrap = root.querySelector(".sw-template-mini-wrap");
    if (wrap) {
      const spec = getTemplateSpecForPost(post, "mini");
      const data = adaptPostToTemplateData(post);
      root.__swUnmount = mountCard(wrap, spec, data, theme);
    }

    clearOcclusion(markersRef);
  }

  renderCompact();
  root.__renderCompact = renderCompact;

  const marker = new maplibregl.Marker({ element: root, anchor: "bottom" })
    .setLngLat(lngLat)
    .addTo(map);

  markersRef.current.push({ id: post.id, marker, el: root, post });

  root.addEventListener("click", (ev) => {
    ev.stopPropagation();

    const existing = map.__swCenteredOverlay;
    if (existing && existing.postId === post?.id) {
      closeCenteredOverlay(map);
      return;
    }

    openCenteredOverlay({ map, post, theme });
    if (expandedElRef) expandedElRef.current = null;
  });
}
