/* global React */
// Shared building blocks: icons, stars, source badge, avatar, reveal observer

const { useEffect, useRef, useState, useMemo } = React;

// ---------- Icons ----------
const IconStar = ({ filled = true, color }) => (
  <svg className="star" viewBox="0 0 24 24" aria-hidden="true">
    <path
      d="M12 2.5l2.92 6.36 6.96.71-5.2 4.7 1.49 6.83L12 17.6l-6.17 3.5 1.49-6.83-5.2-4.7 6.96-.71L12 2.5z"
      fill={filled ? (color || "#00B67A") : "transparent"}
      stroke={filled ? "transparent" : "#C9C0AC"}
      strokeWidth="1.4"
    />
  </svg>
);

const IconCheck = (props) => (
  <svg viewBox="0 0 16 16" aria-hidden="true" {...props}>
    <path d="M3 8.5l3 3 7-7" stroke="currentColor" strokeWidth="1.6" fill="none" strokeLinecap="round" strokeLinejoin="round" />
  </svg>
);

const IconArrow = (props) => (
  <svg width="14" height="14" viewBox="0 0 14 14" aria-hidden="true" {...props}>
    <path d="M2 7h10M8 3l4 4-4 4" stroke="currentColor" strokeWidth="1.4" fill="none" strokeLinecap="round" strokeLinejoin="round" />
  </svg>
);

const IconSend = (props) => (
  <svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true" {...props}>
    <path d="M3 12l18-9-7 18-3-7-8-2z" fill="currentColor" />
  </svg>
);

// ---------- Stars ----------
function Stars({ rating, size = "md" }) {
  const r = Math.round(rating);
  const cls = size === "lg" ? "star-row lg" : "star-row";
  // Trustpilot-style: filled green for the rating amount, grey outline for rest
  return (
    <span className={cls} aria-label={`${rating} out of 5 stars`}>
      {[1, 2, 3, 4, 5].map((i) => (
        <span
          key={i}
          style={{
            display: "inline-grid",
            placeItems: "center",
            width: size === "lg" ? 26 : 18,
            height: size === "lg" ? 26 : 18,
            background: i <= r ? "#00B67A" : "transparent",
            border: i <= r ? "none" : "1px solid #D4CCB8",
            borderRadius: 2,
          }}
        >
          <svg viewBox="0 0 24 24" width={size === "lg" ? 18 : 12} height={size === "lg" ? 18 : 12} aria-hidden="true">
            <path
              d="M12 2.5l2.92 6.36 6.96.71-5.2 4.7 1.49 6.83L12 17.6l-6.17 3.5 1.49-6.83-5.2-4.7 6.96-.71L12 2.5z"
              fill={i <= r ? "#ffffff" : "#D4CCB8"}
            />
          </svg>
        </span>
      ))}
    </span>
  );
}

// ---------- Source badge ----------
function SourceBadge({ source }) {
  const label = source === "trustpilot" ? "Trustpilot" : source === "google" ? "Google" : "Direct";
  return (
    <span className="review-source">
      <span className={`review-source-mark ${source}`}></span>
      {label}
    </span>
  );
}

// ---------- Avatar ----------
function Avatar({ initials, seed }) {
  // Deterministic tint based on seed string
  let h = 0;
  for (let i = 0; i < (seed || "").length; i++) h = (h * 31 + seed.charCodeAt(i)) >>> 0;
  const tint = ["t1", "t2", "t3", "t4"][h % 4];
  return <span className={`avatar ${tint}`} aria-hidden="true">{initials}</span>;
}

// ---------- Reveal on scroll ----------
function useReveal() {
  useEffect(() => {
    const els = document.querySelectorAll(".reveal");
    if (!("IntersectionObserver" in window) || els.length === 0) {
      els.forEach((el) => el.classList.add("is-visible"));
      return;
    }
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            e.target.classList.add("is-visible");
            io.unobserve(e.target);
          }
        });
      },
      { rootMargin: "0px 0px -10% 0px", threshold: 0.05 }
    );
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  });
}

// ---------- Format date ----------
function formatDate(iso) {
  const d = new Date(iso);
  return d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
}

function timeAgo(iso) {
  const then = new Date(iso).getTime();
  const now = Date.now();
  const diff = Math.max(0, now - then);
  const days = Math.floor(diff / 86400000);
  if (days < 1) return "Today";
  if (days < 30) return `${days}d ago`;
  const months = Math.floor(days / 30);
  if (months < 12) return `${months}mo ago`;
  const years = Math.floor(days / 365);
  return `${years}y ago`;
}

Object.assign(window, {
  IconStar, IconCheck, IconArrow, IconSend,
  Stars, SourceBadge, Avatar,
  useReveal, formatDate, timeAgo,
});
