"use client";

import { forwardRef, useEffect, useState } from "react";
import type { DeviceTarget } from "./devices";
import { FRAME_IPAD } from "./frames";
import type { ScreenSpec } from "./screens";
import {
  DeviceMock,
  ScreenshotThemeContext,
  type ScreenshotTheme,
} from "./device-mock";
import { EnodeProLockup } from "./enode-pro-lockup";
import dotCloud from "./assets/dot-cloud.svg";

// One marketing tile, laid out at the target's EXACT export pixel size. The
// forwarded ref points at the capture node (`exportTileJpeg` shoots it at
// scale 1 → pixel-exact JPEG). Everything scales off `unit` (relative to the
// 1320px-wide iPhone tile) so tiles read consistently across sizes.
//
// The device bezel is sized to FIT the area below the headline: a portrait
// phone is width-limited, a landscape tablet is height-limited. We measure the
// device region (a flex-1 box whose height is whatever's left under the
// branding) and pick the bezel width that keeps the whole device inside it —
// so a wide landscape iPad never overflows the tile.
export const MarketingTile = forwardRef<
  HTMLDivElement,
  { screen: ScreenSpec; target: DeviceTarget; mode?: ScreenshotTheme }
>(function MarketingTile({ screen, target, mode = "dark" }, ref) {
  const unit = target.exportW / 1320;
  const pad = Math.round(80 * unit);
  const light = mode === "light";

  // The landscape-tablet frames (iPad + Android tablet both reuse FRAME_IPAD)
  // are HEIGHT-limited: the device fills whatever height is left under the
  // branding. Shrinking the headline / category there frees vertical room, so
  // the frame renders bigger. Phones (width-limited) and the Mac keep the full
  // type scale.
  // The Android ecosystem hero lays the branding out on the LEFT with the
  // device composition filling the right — a horizontal split, not the usual
  // top-branding / device-below stack.
  const heroLeftText = screen.hero && target.id === "hero-android";
  const isTabletFrame = target.frame === FRAME_IPAD;
  // The Android tablet tile is the widest/shortest landscape target, so its
  // frame is the most height-constrained — give it an extra nudge (smaller
  // headline + tighter margins below) so it fills more of the tile.
  const isAndroidTablet = target.id === "android-tablet";
  const headlineFont = Math.round(
    (heroLeftText ? 54 : isAndroidTablet ? 44 : isTabletFrame ? 52 : 76) * unit,
  );
  const categoryFont = Math.round((isTabletFrame ? 26 : 34) * unit);
  const pointFont = Math.round(25 * unit);

  // Measure the region the device sits in (its height is set by flex-1 after
  // the branding takes its natural height). Callback ref + ResizeObserver so
  // the measure runs once the node mounts, even off-screen for capture.
  const [region, setRegion] = useState<HTMLDivElement | null>(null);
  const [regionSize, setRegionSize] = useState<{ w: number; h: number } | null>(
    null,
  );
  useEffect(() => {
    if (!region) return;
    const measure = () =>
      setRegionSize({ w: region.clientWidth, h: region.clientHeight });
    measure();
    const observer = new ResizeObserver(measure);
    observer.observe(region);
    return () => observer.disconnect();
  }, [region]);

  // Fit the device FRAME to the region by BOTH axes; a small margin keeps it off
  // the region edges. Until measured, fall back to a width-based guess. The
  // frame's outer aspect (height / width) drives the height-limited fit.
  const outerAspect = target.frame ? 1 / target.frame.aspect : 1; // frame h / w
  const margin = Math.round((isAndroidTablet ? 10 : 24) * unit);
  const widthCap = target.exportW * 0.82 - 2 * pad;
  const deviceWidth = regionSize
    ? Math.min(
        regionSize.w - 2 * margin,
        (regionSize.h - 2 * margin) / outerAspect,
      )
    : widthCap;

  return (
    <ScreenshotThemeContext.Provider value={mode}>
    <div
      ref={ref}
      className={`relative flex overflow-hidden ${
        heroLeftText ? "flex-row items-stretch" : "flex-col items-center"
      }`}
      style={{
        width: target.exportW,
        height: target.exportH,
        background: light
          ? "radial-gradient(120% 80% at 50% 0%, #ffffff 0%, #eef0f2 60%)"
          : "radial-gradient(120% 80% at 50% 0%, #17181c 0%, #0b0b0d 60%)",
        color: light ? "#0b0b0d" : "#fafafa",
        paddingLeft: pad,
        paddingRight: pad,
        paddingTop: heroLeftText ? pad : Math.round(96 * unit),
      }}
    >
      {/* enode dot-cloud branding texture — a faint field behind everything.
          Inverted to dark dots on the light background. */}
      {/* eslint-disable-next-line @next/next/no-img-element */}
      <img
        src={dotCloud.src}
        alt=""
        aria-hidden
        className="pointer-events-none absolute inset-0 z-0 h-full w-full object-cover"
        style={{
          opacity: light ? 0.1 : 0.14,
          filter: light ? "invert(1)" : undefined,
        }}
      />

      {/* Branding + headline — above the device region so a hero composition can
          bleed up behind it as a backdrop without covering the text. For the
          Android hero it's a vertically-centred LEFT column instead. */}
      <div
        className={`relative z-20 flex flex-col items-start ${
          heroLeftText ? "w-[45%] shrink-0 justify-center" : "w-full"
        }`}
        style={{
          gap: Math.round(28 * unit),
          paddingRight: heroLeftText ? Math.round(48 * unit) : undefined,
        }}
      >
        <EnodeProLockup heightPx={Math.round(44 * unit)} />
        <div className="flex items-center" style={{ gap: Math.round(14 * unit), marginTop: Math.round(24 * unit) }}>
          <span
            className="rounded-full"
            style={{
              width: Math.round(14 * unit),
              height: Math.round(14 * unit),
              background: "var(--foreground-red-orange, #ff4805)",
            }}
          />
          <span
            className="font-medium"
            style={{
              fontSize: categoryFont,
              color: light ? "#5f6570" : "#c9cace",
            }}
          >
            {screen.category}
          </span>
        </div>
        <h2
          className="font-semibold"
          style={{
            fontSize: headlineFont,
            lineHeight: 1.05,
            letterSpacing: `${-0.02 * unit}em`,
            maxWidth: "16em",
          }}
        >
          {heroLeftText && screen.heroHeadline
            ? screen.heroHeadline
            : screen.headline}
        </h2>

        {/* Value points — the left-text hero's supporting pitch. */}
        {heroLeftText && screen.heroPoints && (
          <ul
            className="flex flex-col"
            style={{ gap: Math.round(22 * unit), marginTop: Math.round(12 * unit) }}
          >
            {screen.heroPoints.map((point) => (
              <li
                key={point}
                className="flex items-start"
                style={{ gap: Math.round(18 * unit) }}
              >
                <span
                  className="shrink-0 rounded-full"
                  style={{
                    width: Math.round(12 * unit),
                    height: Math.round(12 * unit),
                    marginTop: Math.round(pointFont * 0.42),
                    background: "var(--foreground-red-orange, #ff4805)",
                  }}
                />
                <span
                  style={{
                    fontSize: pointFont,
                    lineHeight: 1.3,
                    color: light ? "#3a3f47" : "#d5d6da",
                  }}
                >
                  {point}
                </span>
              </li>
            ))}
          </ul>
        )}
      </div>

      {/* Device region — takes the remaining height; the bezel is fitted to it
          (width-limited in portrait, height-limited in landscape). */}
      <div
        ref={setRegion}
        className={`relative z-10 flex min-h-0 flex-1 items-center justify-center ${
          heroLeftText ? "" : "w-full"
        } ${screen.hero ? "" : "overflow-hidden"}`}
        style={{
          marginTop: heroLeftText
            ? 0
            : Math.round((isAndroidTablet ? 20 : 40) * unit),
        }}
      >
        {/* Hero (frameless) screens compose their own device frames; every other
            screen is wrapped in a single fitted device frame. */}
        {screen.hero ? (
          screen.render(target)
        ) : deviceWidth > 0 ? (
          <DeviceMock target={target} frameWidthPx={Math.round(deviceWidth)}>
            {screen.render(target)}
          </DeviceMock>
        ) : null}
      </div>
    </div>
    </ScreenshotThemeContext.Provider>
  );
});
