/* ============ BUSINESS — categorized works marquee (replaces old Intro slot) ============
   Each lane pulls works whose `cat` tags match the lane's tag list. A lane only scrolls
   when its items actually overflow the viewport; if they fit, it stays static. */
const BUSINESS_LANES = [
  { label: "システム開発", tags: ["システム開発"], dir: "rtl" },
  { label: "イベント予約や決済アプリ開発", tags: ["イベント予約", "決済"], dir: "ltr" },
  { label: "寮のアプリ開発", tags: ["寮管理", "寮アプリ"], dir: "rtl" },
];

/* DeviceFrame's phone/hardware/tablet/doc variants are fixed-px in demo.css already;
   only "desktop" uses width:100% internally, so it alone needs an explicit parent width. */
function laneFrameStyle(device) {
  return device === "desktop" ? { width: 380 } : undefined;
}

/* Real demo screens skip DeviceFrame (see below) and instead sit in a work-thumb box —
   give that box the device's own aspect ratio so it hugs the mockup tightly instead of
   centering it inside a generic wide 4:3 frame with dead space (and a mismatched hover area). */
const LANE_DEMO_ASPECT = { phone: "300/620", tablet: "4/3", desktop: "16/10", hardware: "5/3", doc: "1/1.41" };
function laneDemoStyle(device) {
  return { aspectRatio: LANE_DEMO_ASPECT[device] || LANE_DEMO_ASPECT.phone };
}

/* Backdrop thumbnails are a plain cropped screenshot, not the full WorkPrototypeThumb —
   that component draws the same thick phone-bezel chrome used for the big grid cards,
   which is way oversized for a 132px strip thumb (fat border, huge corner radius,
   spilling past the box). A flat cover-fit image crops cleanly to the tiny frame. */
function LaneBackVisual({ w, idx }) {
  const cfg = w.demoConfig || {};
  const screens = w.demo && Array.isArray(cfg.screens) ? orderScreens(cfg.screens, cfg.initial) : [];
  const shot = screens[0] && screens[0].image;
  if (shot) return <img className="lane-back-shot" src={shot} alt={w.title || w.en || "work"} loading="lazy" />;
  return <Placeholder label={String(w.en || w.title || w.id || "WORK").toUpperCase()} k={idx} />;
}

/* One "featured" work gets the big device mockup up front; the rest of the lane's
   works pass by as flat thumbnails in a backdrop strip behind it. The strip always
   sweeps the FULL width of the stage — entering from one edge, crossing past the
   other, then looping — regardless of item count. The classic "double the content,
   shift by half its own width" filmstrip loop only reads as motion once there's
   enough content to overflow the stage; with just one or two items it stays parked
   near the stage's left edge — right where the feature mockup already sits — so it
   never visibly clears it or crosses the open space beside it. */
function Lane({ label, works, dir, alt, onFocusWork }) {
  const viewportRef = useRef(null);
  const trackRef = useRef(null);
  const [travel, setTravel] = useState({ start: 0, end: 0, duration: 22 });

  const feature = works[0];
  const backdrop = works.slice(1);
  const hasBackdrop = backdrop.length > 0;

  useLayoutEffect(() => {
    const vp = viewportRef.current, track = trackRef.current;
    if (!vp || !track || !hasBackdrop) return;
    const speedPxPerSec = 40;
    const measure = () => {
      const containerW = vp.clientWidth;
      const contentW = track.scrollWidth;
      setTravel({ start: containerW, end: -contentW, duration: Math.max(8, (containerW + contentW) / speedPxPerSec) });
    };
    measure();
    const ro = new ResizeObserver(measure);
    ro.observe(vp);
    ro.observe(track);
    return () => ro.disconnect();
  }, [hasBackdrop, backdrop.length]);

  if (!works.length) {
    return (
      <div className={`lane ${alt ? "lane-alt" : ""}`}>
        <div className="lane-feature-copy">
          <h3 className="lane-title">{label}</h3>
          <span className="mono lane-count">00 WORKS</span>
        </div>
        <p className="lane-empty">準備中</p>
      </div>
    );
  }

  const open = (id) => onFocusWork(id);
  const keyOpen = (e, id) => { if (e.key === "Enter") onFocusWork(id); };

  return (
    <div className={`lane ${alt ? "lane-alt" : ""}`}>
      <div className="lane-stage">
        {hasBackdrop && (
          <div className="lane-backdrop" ref={viewportRef}>
            <div
              ref={trackRef}
              className={`lane-backdrop-track dir-${dir}`}
              style={{ "--lane-start": `${travel.start}px`, "--lane-end": `${travel.end}px`, "--lane-dur": `${travel.duration}s` }}
            >
              {backdrop.map((w, i) => (
                <div
                  key={w.id + "-" + i}
                  className="lane-back-item"
                  onClick={() => open(w.id)}
                  role="button"
                  tabIndex={0}
                  onKeyDown={(e) => keyOpen(e, w.id)}
                >
                  <div className={`lane-back-thumb ${w.device || "phone"}`} style={laneDemoStyle(w.device)}><LaneBackVisual w={w} idx={i} /></div>
                </div>
              ))}
            </div>
          </div>
        )}
        <div
          className="lane-feature"
          onClick={() => open(feature.id)}
          role="button"
          tabIndex={0}
          onKeyDown={(e) => keyOpen(e, feature.id)}
        >
          <div
            className={`lane-feature-frame ${feature.demo ? "work-thumb lane-feature-demo" : ""}`}
            style={feature.demo ? laneDemoStyle(feature.device) : laneFrameStyle(feature.device)}
          >
            {feature.demo ? (
              /* WorkPrototypeThumb already draws its own phone/tablet/desktop chrome around
                 real demo screens — wrapping it in DeviceFrame here would double it up, so it
                 just gets the same work-thumb positioning box the Works grid cards use. */
              <div className="work-thumb-inner"><WorkPrototypeThumb w={feature} idx={0} /></div>
            ) : (
              <DeviceFrame type={feature.device} label={String(feature.en || feature.id || "work").toLowerCase() + ".app"}>
                <WorkPrototypeThumb w={feature} idx={0} />
              </DeviceFrame>
            )}
          </div>
          <div className="lane-feature-copy">
            <h3 className="lane-title">{label}</h3>
            <p className="lane-feature-name">{feature.title}<span className="mono">{feature.en}</span></p>
            <span className="mono lane-count">{String(works.length).padStart(2, "0")} WORKS</span>
          </div>
        </div>
      </div>
    </div>
  );
}

function BusinessSection({ onFocusWork }) {
  const all = (window.HASHBIT_DATA && window.HASHBIT_DATA.works) || [];
  const lanes = BUSINESS_LANES.map(l => ({
    ...l,
    works: all.filter(w => (w.cat || []).some(c => l.tags.includes(c)))
  }));

  return (
    <section className="business section" id="business">
      <div className="wrap">
        <div className="sec-head">
          <div className="eyebrow"><span className="idx">02</span> Business</div>
          <div className="mono sec-co">HASHBIT / 事業内容</div>
        </div>
        <div className="business-panel">
          {lanes.map((l, i) => (
            <React.Fragment key={l.label}>
              {i > 0 && <div className={`lane-cut ${i % 2 ? "cut-a" : "cut-b"}`} aria-hidden="true"></div>}
              <Lane label={l.label} works={l.works} dir={l.dir} alt={i % 2 === 1} onFocusWork={onFocusWork} />
            </React.Fragment>
          ))}
        </div>
      </div>
    </section>
  );
}

window.BusinessSection = BusinessSection;
