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

const INFRASTRUCTURE_LABELS = new Set([
  "www",
  "app",
  "web",
  "webmd",
  "labs",
  "lab",
  "live",
  "prod",
  "production",
  "stage",
  "staging",
  "dev",
  "preview",
  "test",
]);

const ENVIRONMENT_LABELS = [
  ["labs", "Labs"],
  ["lab", "Labs"],
  ["live", "Live"],
  ["prod", "Live"],
  ["production", "Live"],
  ["stage", "Stage"],
  ["staging", "Stage"],
  ["dev", "Development"],
  ["preview", "Preview"],
  ["test", "Test"],
];

function titleCase(value) {
  return value
    .replace(/[-_]+/g, " ")
    .replace(/([a-z])([A-Z])/g, "$1 $2")
    .split(/\s+/)
    .filter(Boolean)
    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
    .join(" ");
}

function getDomainContext() {
  const rawHost = window.location.hostname || "preview.local";
  const hostname = rawHost.toLowerCase().replace(/\.$/, "");
  const isLocal = hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1";
  const labels = hostname.split(".").filter(Boolean);
  const environment = ENVIRONMENT_LABELS.find(([key]) => labels.includes(key))?.[1] || (isLocal ? "Local" : "Preview");
  const meaningful = labels.filter((label, index) => {
    const isTld = index === labels.length - 1;
    return !isTld && !INFRASTRUCTURE_LABELS.has(label);
  });
  const brandLabel = meaningful[0] || labels[0] || "New site";
  const brand = isLocal ? "Local Preview" : titleCase(brandLabel);
  const rootDomain = labels.length > 1 ? labels.slice(-2).join(".") : hostname;

  return {
    hostname,
    brand,
    environment,
    rootDomain,
    isLocal,
  };
}

function SignalCanvas({ seed }) {
  const canvasRef = useRef(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    const context = canvas.getContext("2d");
    const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const palette = ["#177c72", "#c44e35", "#2d67a3", "#d18a1d"];
    let width = 0;
    let height = 0;
    let frame = 0;
    let animationId = 0;
    let pointer = { x: 0.72, y: 0.28 };

    const seedValue = Array.from(seed).reduce((total, character) => total + character.charCodeAt(0), 0);
    const nodes = Array.from({ length: 18 }, (_, index) => ({
      x: ((index * 71 + seedValue) % 100) / 100,
      y: ((index * 43 + seedValue * 2) % 100) / 100,
      color: palette[index % palette.length],
      speed: 0.0006 + (index % 4) * 0.00016,
      axis: index % 2,
    }));

    function resize() {
      const rect = canvas.getBoundingClientRect();
      const ratio = Math.min(window.devicePixelRatio || 1, 2);
      width = Math.max(1, rect.width);
      height = Math.max(1, rect.height);
      canvas.width = Math.floor(width * ratio);
      canvas.height = Math.floor(height * ratio);
      context.setTransform(ratio, 0, 0, ratio, 0, 0);
    }

    function draw() {
      context.fillStyle = "#f2f6f4";
      context.fillRect(0, 0, width, height);

      context.strokeStyle = "rgba(23, 32, 31, 0.08)";
      context.lineWidth = 1;
      const grid = width < 700 ? 42 : 58;
      for (let x = 0; x <= width; x += grid) {
        context.beginPath();
        context.moveTo(x, 0);
        context.lineTo(x, height);
        context.stroke();
      }
      for (let y = 0; y <= height; y += grid) {
        context.beginPath();
        context.moveTo(0, y);
        context.lineTo(width, y);
        context.stroke();
      }

      const focusX = pointer.x * width;
      const focusY = pointer.y * height;
      context.strokeStyle = "rgba(45, 103, 163, 0.18)";
      context.lineWidth = 2;
      context.beginPath();
      context.arc(focusX, focusY, 68, 0, Math.PI * 1.65);
      context.stroke();

      nodes.forEach((node, index) => {
        const travel = reduceMotion ? 0 : frame * node.speed;
        const shifted = (node.axis ? node.y : node.x) + travel;
        const progress = shifted % 1;
        const x = node.axis ? node.x * width : progress * width;
        const y = node.axis ? progress * height : node.y * height;
        const size = 6 + (index % 3) * 3;

        context.fillStyle = node.color;
        context.fillRect(x - size / 2, y - size / 2, size, size);

        context.strokeStyle = "rgba(23, 32, 31, 0.14)";
        context.beginPath();
        context.moveTo(x, y);
        context.lineTo(focusX, focusY);
        context.stroke();
      });

      frame += 1;
      if (!reduceMotion) {
        animationId = window.requestAnimationFrame(draw);
      }
    }

    function handlePointer(event) {
      const rect = canvas.getBoundingClientRect();
      pointer = {
        x: Math.max(0, Math.min(1, (event.clientX - rect.left) / rect.width)),
        y: Math.max(0, Math.min(1, (event.clientY - rect.top) / rect.height)),
      };
    }

    resize();
    draw();
    window.addEventListener("resize", resize);
    canvas.addEventListener("pointermove", handlePointer);

    return () => {
      window.cancelAnimationFrame(animationId);
      window.removeEventListener("resize", resize);
      canvas.removeEventListener("pointermove", handlePointer);
    };
  }, [seed]);

  return <canvas ref={canvasRef} className="signal-canvas" aria-hidden="true" />;
}

function App() {
  const domain = useMemo(getDomainContext, []);
  const [copied, setCopied] = useState(false);
  const [time, setTime] = useState(() => new Date());

  useEffect(() => {
    document.title = `${domain.brand} | Work in progress`;
    const timer = window.setInterval(() => setTime(new Date()), 60_000);
    return () => window.clearInterval(timer);
  }, [domain.brand]);

  useEffect(() => {
    if (window.lucide) {
      window.lucide.createIcons({ attrs: { "stroke-width": 1.8 } });
    }
  }, [copied]);

  async function copyHostname() {
    try {
      await navigator.clipboard.writeText(domain.hostname);
    } catch {
      const input = document.createElement("textarea");
      input.value = domain.hostname;
      input.setAttribute("readonly", "");
      input.style.position = "fixed";
      input.style.opacity = "0";
      document.body.appendChild(input);
      input.select();
      document.execCommand("copy");
      input.remove();
    }
    setCopied(true);
    window.setTimeout(() => setCopied(false), 1600);
  }

  const timeLabel = new Intl.DateTimeFormat(undefined, {
    hour: "2-digit",
    minute: "2-digit",
    timeZoneName: "short",
  }).format(time);

  return (
    <div className="site-shell">
      <header className="topbar">
        <div className="brand-lockup">
          <span className="brand-mark" aria-hidden="true" />
          <span className="brand-name">{domain.brand}</span>
        </div>
        <div className="header-state">
          <span className="state-dot" aria-hidden="true" />
          <span>Work in progress</span>
        </div>
      </header>

      <main>
        <section className="hero" aria-labelledby="page-title">
          <SignalCanvas seed={domain.hostname} />
          <div className="hero-content">
            <p className="eyebrow"><span className="eyebrow-line" aria-hidden="true" />Temporary workspace</p>
            <h1 id="page-title"><span className="domain-name">{domain.brand}</span> is taking shape.</h1>
            <p className="lead">A focused temporary home is online while the next release is prepared, reviewed, and connected.</p>

            <div className="host-row" aria-label="Detected hostname">
              <span className="host-label">Current address</span>
              <code className="host-value" title={domain.hostname}>{domain.hostname}</code>
              <button className="icon-button" type="button" onClick={copyHostname} title={copied ? "Copied" : "Copy hostname"} aria-label={copied ? "Hostname copied" : "Copy hostname"}>
                <i data-lucide={copied ? "check" : "copy"} aria-hidden="true" />
              </button>
            </div>

            <div className="phase-track" aria-label="Launch progress">
              <div className="phase is-ready"><div className="phase-bar" /><span className="phase-label">Domain ready</span></div>
              <div className="phase is-active"><div className="phase-bar" /><span className="phase-label">Build active</span></div>
              <div className="phase"><div className="phase-bar" /><span className="phase-label">Launch next</span></div>
            </div>
          </div>
        </section>

        <section className="details" aria-labelledby="details-heading">
          <h2 className="detail-heading" id="details-heading">Current signal</h2>
          <div className="detail-grid">
            <article className="detail-item">
              <p className="detail-kicker">Domain</p>
              <p className="detail-value">{domain.rootDomain}</p>
              <p className="detail-note">Detected directly from this browser request.</p>
            </article>
            <article className="detail-item">
              <p className="detail-kicker">Environment</p>
              <p className="detail-value">{domain.environment}</p>
              <p className="detail-note">The same template adapts across temporary facades.</p>
            </article>
            <article className="detail-item">
              <p className="detail-kicker">Status</p>
              <p className="detail-value">Release preparation</p>
              <p className="detail-note">Last viewed at {timeLabel}.</p>
            </article>
          </div>
        </section>
      </main>

      <footer className="footer">
        <span>{domain.hostname}</span>
        <span>Temporary domain-aware preview</span>
      </footer>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
