// COVIA Works — Marquee Portfolio
// Auto-scrolling carousel of project cards, hover pauses, click expands detail panel.
// Tripled items for seamless loop on ultra-wide screens.
//
// Data source: window.COVIA_WORKS (loaded by data/works-loader.js from works.json)
// Helpers:     window.CoviaWorksUtils.{ resolvePrimaryLink, isExternal, resolveDisplayHost }

const COVIA_WORKS_FALLBACK = [
  {
    num: '01', title: 'COVIA', tag: 'Web · Platform',
    tagline: '知識共享 × 個人 HUB',
    intro: '資料載入失敗，請重新整理頁面。',
    year: '2025', image: null,
    links: { website: '/', repo: null, docs: null },
  },
];

function CoviaWorks() {
  const { lang, t } = useLang();
  const sectionRef = React.useRef(null);
  const [focusedIdx, setFocusedIdx] = React.useState(0);
  const [revealed, setRevealed] = React.useState(false);
  const [projects, setProjects] = React.useState(window.COVIA_WORKS || []);

  React.useEffect(() => {
    if (Array.isArray(window.COVIA_WORKS) && window.COVIA_WORKS.length > 0) {
      setProjects(window.COVIA_WORKS);
      return;
    }
    const onReady = (e) => {
      const data = (e && e.detail) || window.COVIA_WORKS || [];
      setProjects(Array.isArray(data) && data.length > 0 ? data : COVIA_WORKS_FALLBACK);
    };
    window.addEventListener('covia:works-ready', onReady);
    if (window.COVIA_WORKS_READY && typeof window.COVIA_WORKS_READY.then === 'function') {
      window.COVIA_WORKS_READY.then((data) => {
        if (!Array.isArray(data) || data.length === 0) setProjects(COVIA_WORKS_FALLBACK);
      });
    }
    return () => window.removeEventListener('covia:works-ready', onReady);
  }, []);

  React.useEffect(() => {
    if (!sectionRef.current) return;
    const obs = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        setRevealed(true);
        obs.disconnect();
      }
    }, { threshold: 0.15 });
    obs.observe(sectionRef.current);
    return () => obs.disconnect();
  }, []);

  React.useEffect(() => {
    const onKey = (e) => {
      const section = sectionRef.current;
      if (!section) return;
      const rect = section.getBoundingClientRect();
      const inView = rect.top < window.innerHeight * 0.5 && rect.bottom > window.innerHeight * 0.5;
      if (!inView) return;

      if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
        e.preventDefault();
        setFocusedIdx(i => Math.min(projects.length - 1, i + 1));
      } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
        e.preventDefault();
        setFocusedIdx(i => Math.max(0, i - 1));
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [projects.length]);

  const utils = window.CoviaWorksUtils || {
    resolvePrimaryLink: (p) => p && p.links && (p.links.website || p.links.repo || p.links.docs) || null,
    isExternal: (u) => !!u && /^https?:\/\//i.test(u),
    resolveDisplayHost: (u) => {
      if (!u) return 'TBD';
      if (u === '/') return 'covia.io';
      if (u.startsWith('/')) return 'covia.io' + u;
      try { return new URL(u).hostname.replace(/^www\./, ''); } catch (_) { return u; }
    },
  };

  if (!projects || projects.length === 0) {
    return (
      <section ref={sectionRef} id="works" className="works-rev">
        <div className="works-rev-inner" style={{ display: 'grid', placeItems: 'center', minHeight: '60vh' }}>
          <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--text-2)', fontSize: 11, letterSpacing: '0.2em' }}>{t('works.loading')}</span>
        </div>
      </section>
    );
  }

  const p = projects[focusedIdx];
  const primary = utils.resolvePrimaryLink(p);
  const host = utils.resolveDisplayHost(primary);
  const external = utils.isExternal(primary);
  const clickable = !!primary;
  const apps = tField(p, 'applications');
  const marqueeItems = [...projects, ...projects, ...projects];

  return (
    <section ref={sectionRef} id="works" className={'works-rev' + (revealed ? ' is-revealed' : '')}>
      <div className="works-rev-inner">
        <header className="works-rev-header">
          <div className="works-rev-chapter">
            <span className="works-rev-chapter-num">01</span>
            <span className="works-rev-chapter-label">Works · Portfolio</span>
          </div>
          <div className="works-rev-counter">
            <span className="works-rev-counter-cur">{p.num}</span>
            <span className="works-rev-counter-sep"> / </span>
            <span className="works-rev-counter-tot">{String(projects.length).padStart(2, '0')}</span>
          </div>
        </header>

        <div className="works-rev-marquee" ref={(el) => {
          if (!el || el._dragInit) return;
          el._dragInit = true;
          let isDrag = false, startX = 0, scrollStart = 0;
          const onDown = (e) => {
            isDrag = true;
            startX = (e.touches ? e.touches[0].clientX : e.clientX);
            scrollStart = el.scrollLeft;
            el.classList.add('is-dragging');
          };
          const onMove = (e) => {
            if (!isDrag) return;
            const x = e.touches ? e.touches[0].clientX : e.clientX;
            el.scrollLeft = scrollStart - (x - startX);
          };
          const onUp = () => {
            isDrag = false;
            el.classList.remove('is-dragging');
          };
          el.addEventListener('mousedown', onDown);
          el.addEventListener('mousemove', onMove);
          el.addEventListener('mouseup', onUp);
          el.addEventListener('mouseleave', onUp);
          el.addEventListener('touchstart', onDown, { passive: true });
          el.addEventListener('touchmove', onMove, { passive: true });
          el.addEventListener('touchend', onUp);
        }}>
          <div className="works-rev-track">
            {marqueeItems.map((proj, i) => {
              const realIdx = i % projects.length;
              const suffix = i < projects.length ? '' : i < projects.length * 2 ? '-b' : '-c';
              return (
                <button
                  key={proj.num + suffix}
                  className={'works-rev-card' + (realIdx === focusedIdx ? ' is-active' : '')}
                  onClick={() => setFocusedIdx(realIdx)}
                  aria-label={tField(proj, 'title')}
                >
                  <span className="works-rev-card-visual">
                    {proj.image
                      ? React.createElement('img', { src: proj.image, alt: '', className: 'works-rev-card-img' })
                      : <span className="works-rev-card-glyph">{proj.num}</span>}
                  </span>
                  <span className="works-rev-card-info">
                    <span className="works-rev-card-title">{tField(proj, 'title')}</span>
                    <span className="works-rev-card-tag">{proj.tag}</span>
                  </span>
                </button>
              );
            })}
          </div>
        </div>

        <article className="works-rev-panel" key={focusedIdx} role="region">
          <div className="works-rev-panel-visual">
            {p.image
              ? React.createElement('img', { src: p.image, alt: p.title, className: 'works-rev-panel-img' })
              : <span className="works-rev-panel-glyph">{p.num}</span>}
          </div>
          <div className="works-rev-panel-body">
            <div className="works-rev-panel-meta-top">
              <span className="works-rev-panel-tag">{p.tag}</span>
              <span className="works-rev-panel-year">{p.year}</span>
            </div>
            <h3 className="works-rev-panel-tagline">{tField(p, 'tagline')}</h3>
            {Array.isArray(p.tech_stack) && p.tech_stack.length > 0 && (
              <div className="works-rev-panel-techstack">
                {p.tech_stack.map((tech, j) => (
                  <span key={j} className="works-rev-panel-chip">{tech}</span>
                ))}
              </div>
            )}
            <p className="works-rev-panel-intro">{tField(p, 'intro')}</p>
            {Array.isArray(apps) && apps.length > 0 && (
              <div className="works-rev-panel-apps">
                {apps.map((a, j) => (
                  <span key={j} className="works-rev-panel-app">{a}</span>
                ))}
              </div>
            )}
            <div className="works-rev-panel-bottom">
              {clickable ? (
                <a
                  href={primary}
                  target={external ? '_blank' : undefined}
                  rel={external ? 'noopener noreferrer' : undefined}
                  className="works-rev-panel-cta"
                >
                  <span>{host}</span>
                  <span className="works-rev-panel-cta-arrow">↗</span>
                </a>
              ) : (
                <span className="works-rev-panel-cta is-tbd">
                  <span>TBD</span>
                  <span className="works-rev-panel-cta-arrow">—</span>
                </span>
              )}
            </div>
          </div>
        </article>

        <footer className="works-rev-footer">
          <span className="works-rev-footer-rule" />
          <span className="works-rev-footer-mark">{t('works.footer')}</span>
          <span className="works-rev-footer-rule" />
        </footer>
      </div>
    </section>
  );
}

/* ============ Styles ============ */
const worksRevStyle = document.createElement('style');
worksRevStyle.textContent = `
  /* Section */
  .works-rev {
    min-height: 100vh;
    padding: clamp(56px, 8vh, 96px) 0;
    display: flex; flex-direction: column;
  }
  .works-rev-inner {
    width: 100%;
    flex: 1;
    display: flex; flex-direction: column;
    min-height: 0;
    opacity: 0;
    transform: translateY(24px);
    transition: opacity 700ms cubic-bezier(0.16, 1, 0.3, 1),
                transform 700ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .works-rev.is-revealed .works-rev-inner {
    opacity: 1;
    transform: translateY(0);
  }

  /* Header */
  .works-rev-header {
    display: flex; justify-content: space-between; align-items: baseline;
    padding: 0 clamp(24px, 5vw, 80px) 20px;
    border-bottom: 1px solid var(--border-subtle);
    margin-bottom: 0;
  }
  .works-rev-chapter {
    display: flex; align-items: baseline; gap: 12px;
    font-family: var(--font-mono); font-size: 11px;
    letter-spacing: 0.18em; text-transform: uppercase;
    color: var(--text-2);
  }
  .works-rev-chapter-num { color: var(--gold); }
  .works-rev-counter {
    font-family: var(--font-mono); font-size: 13px;
    color: var(--text-1); letter-spacing: 0.08em;
    font-variant-numeric: tabular-nums;
  }
  .works-rev-counter-cur { color: var(--gold); font-weight: 600; }
  .works-rev-counter-sep, .works-rev-counter-tot { color: var(--text-2); }

  /* ─── Marquee ─── */
  .works-rev-marquee {
    position: relative;
    overflow: hidden;
    padding: 20px 0;
    mask-image: linear-gradient(to right,
      transparent 0%, black 8%, black 92%, transparent 100%);
    -webkit-mask-image: linear-gradient(to right,
      transparent 0%, black 8%, black 92%, transparent 100%);
  }
  .works-rev-track {
    display: flex;
    gap: 16px;
    width: max-content;
    animation: marqueeScroll 30s linear infinite;
    padding: 4px 0;
  }
  .works-rev-marquee:hover .works-rev-track,
  .works-rev-marquee.is-dragging .works-rev-track {
    animation-play-state: paused;
  }
  .works-rev-marquee {
    cursor: grab;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .works-rev-marquee::-webkit-scrollbar { display: none; }
  .works-rev-marquee.is-dragging { cursor: grabbing; }
  @keyframes marqueeScroll {
    from { transform: translateX(0); }
    to   { transform: translateX(-33.333%); }
  }

  /* Card */
  .works-rev-card {
    flex-shrink: 0;
    width: clamp(180px, 16vw, 230px);
    height: clamp(130px, 15vh, 180px);
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 8px 8px 6px;
    background:
      radial-gradient(ellipse 80% 60% at 75% 20%, oklch(0.78 0.16 75 / 0.04), transparent 55%),
      linear-gradient(160deg, oklch(0.16 0.01 260), oklch(0.12 0.008 260));
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    cursor: pointer;
    overflow: hidden;
    color: inherit;
    transition: border-color 300ms, transform 380ms cubic-bezier(0.16, 1, 0.3, 1),
                box-shadow 380ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .works-rev-card:hover {
    border-color: oklch(0.78 0.16 75 / 0.35);
    transform: translateY(-6px) scale(1.03);
    box-shadow:
      0 16px 40px -10px oklch(0 0 0 / 0.6),
      0 0 20px oklch(0.78 0.16 75 / 0.08);
  }
  .works-rev-card.is-active {
    border-color: var(--gold);
    box-shadow:
      0 0 0 1px oklch(0.78 0.16 75 / 0.2),
      0 0 24px oklch(0.78 0.16 75 / 0.15);
  }
  .works-rev-card.is-active .works-rev-card-glyph {
    color: oklch(0.3 0.06 75);
    text-shadow: 0 0 60px oklch(0.78 0.16 75 / 0.15);
  }
  .works-rev-card:focus-visible {
    outline: 2px solid var(--gold);
    outline-offset: 2px;
  }

  /* Card visual area */
  .works-rev-card-visual {
    flex: 1;
    display: grid;
    place-items: center;
    width: 100%;
    min-height: 0;
    overflow: hidden;
  }
  .works-rev-card-img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: var(--radius-sm);
    display: block;
    opacity: 0.7;
    transition: opacity 300ms;
  }
  .works-rev-card:hover .works-rev-card-img { opacity: 0.9; }

  /* Card glyph */
  .works-rev-card-glyph {
    font-family: var(--font-display);
    font-size: clamp(48px, 5.5vw, 72px);
    font-weight: 400;
    color: oklch(0.22 0.02 260);
    line-height: 1;
    letter-spacing: -0.03em;
    user-select: none;
    transition: color 300ms, text-shadow 300ms;
    margin-bottom: 6px;
  }

  /* Card info overlay */
  .works-rev-card-info {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    position: relative;
    z-index: 1;
  }
  .works-rev-card-title {
    font-family: var(--font-display);
    font-size: clamp(13px, 1.2vw, 16px);
    font-weight: 400;
    color: var(--text-1);
    letter-spacing: 0.02em;
    transition: color 300ms;
  }
  .works-rev-card.is-active .works-rev-card-title {
    color: var(--gold);
  }
  .works-rev-card:hover .works-rev-card-title {
    color: var(--text-0);
  }
  .works-rev-card-tag {
    font-family: var(--font-mono);
    font-size: 9px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-2);
    opacity: 0.6;
  }

  /* ─── Panel ─── */
  .works-rev-panel {
    flex: 1;
    display: grid;
    grid-template-columns: clamp(200px, 28vw, 380px) 1fr;
    gap: clamp(24px, 4vw, 48px);
    padding: 24px clamp(24px, 5vw, 80px) 16px;
    min-height: 0;
    animation: worksPanelIn 420ms cubic-bezier(0.16, 1, 0.3, 1) both;
  }
  @keyframes worksPanelIn {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: translateY(0); }
  }

  /* Staggered fade-in for panel children */
  .works-rev-panel-visual,
  .works-rev-panel-body > * {
    opacity: 0;
    transform: translateY(10px);
    animation: worksPanelItemIn 450ms cubic-bezier(0.16, 1, 0.3, 1) both;
  }
  @keyframes worksPanelItemIn {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  .works-rev-panel-visual                { animation-delay: 60ms; }
  .works-rev-panel-body > *:nth-child(1) { animation-delay: 100ms; }
  .works-rev-panel-body > *:nth-child(2) { animation-delay: 160ms; }
  .works-rev-panel-body > *:nth-child(3) { animation-delay: 220ms; }
  .works-rev-panel-body > *:nth-child(4) { animation-delay: 280ms; }
  .works-rev-panel-body > *:nth-child(5) { animation-delay: 340ms; }
  .works-rev-panel-body > *:nth-child(6) { animation-delay: 400ms; }
  .works-rev-panel-body > *:nth-child(7) { animation-delay: 440ms; }

  /* Visual */
  .works-rev-panel-visual {
    background:
      radial-gradient(ellipse 70% 50% at 85% 15%, oklch(0.78 0.16 75 / 0.06), transparent 60%),
      linear-gradient(160deg, oklch(0.155 0.01 260), oklch(0.12 0.008 260));
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    overflow: hidden;
    display: grid;
    place-items: center;
    align-self: start;
    min-height: clamp(200px, 28vh, 360px);
    padding: 12px;
    position: relative;
  }
  .works-rev-panel-img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: var(--radius-sm);
    display: block;
  }
  .works-rev-panel-glyph {
    font-family: var(--font-display);
    font-size: clamp(100px, 12vw, 180px);
    font-weight: 400;
    color: oklch(0.22 0.025 260);
    line-height: 0.85;
    letter-spacing: -0.04em;
    user-select: none;
    text-shadow: 0 0 80px oklch(0.78 0.16 75 / 0.06);
  }

  /* Body */
  .works-rev-panel-body {
    display: flex;
    flex-direction: column;
    gap: 14px;
    min-width: 0;
    padding-top: 4px;
  }
  .works-rev-panel-meta-top {
    display: flex;
    align-items: baseline;
    gap: 16px;
  }
  .works-rev-panel-tag {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-2);
  }
  .works-rev-panel-year {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.08em;
    color: var(--text-2);
  }
  .works-rev-panel-tagline {
    font-family: var(--font-display);
    font-size: clamp(20px, 2vw, 28px);
    font-weight: 400;
    line-height: 1.3;
    color: var(--text-0);
    letter-spacing: -0.01em;
    margin: 0;
    text-wrap: pretty;
  }
  .works-rev-panel-techstack {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
  }
  .works-rev-panel-chip {
    font-family: var(--font-mono);
    font-size: 10.5px;
    line-height: 1.35;
    letter-spacing: 0.04em;
    padding: 3px 9px;
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    color: var(--text-2);
    background: oklch(1 0 0 / 0.025);
    white-space: nowrap;
  }
  .works-rev-panel-intro {
    font-size: clamp(13.5px, 1.05vw, 15px);
    line-height: 1.7;
    color: var(--text-1);
    margin: 0;
    text-wrap: pretty;
    max-width: 56ch;
  }
  .works-rev-panel-apps {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
  }
  .works-rev-panel-app {
    font-family: var(--font-mono);
    font-size: 10.5px;
    line-height: 1.35;
    letter-spacing: 0.04em;
    padding: 3px 9px;
    border: 1px solid oklch(1 0 0 / 0.15);
    border-radius: 999px;
    color: var(--text-0);
    background: oklch(1 0 0 / 0.06);
    white-space: nowrap;
  }
  .works-rev-panel-bottom {
    margin-top: auto;
    padding-top: 8px;
  }
  .works-rev-panel-cta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--gold);
    letter-spacing: 0.06em;
    text-decoration: none;
    width: fit-content;
    border-bottom: 1px solid transparent;
    transition: border-color 200ms;
  }
  .works-rev-panel-cta:hover {
    border-bottom-color: var(--gold);
  }
  .works-rev-panel-cta.is-tbd {
    color: var(--text-2);
    cursor: default;
  }
  .works-rev-panel-cta-arrow {
    transition: transform 200ms;
  }
  .works-rev-panel-cta:hover .works-rev-panel-cta-arrow {
    transform: translate(2px, -2px);
  }

  /* Footer */
  .works-rev-footer {
    margin-top: 14px;
    padding: 0 clamp(24px, 5vw, 80px);
    display: flex; align-items: center; gap: 16px;
  }
  .works-rev-footer-rule {
    flex: 1; height: 1px;
    background: var(--border-subtle);
  }
  .works-rev-footer-mark {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--text-2);
  }

  /* Responsive — stack panel vertically on narrow screens */
  @media (max-width: 860px) {
    .works-rev-panel {
      grid-template-columns: 1fr;
      gap: 20px;
    }
    .works-rev-panel-visual {
      min-height: clamp(160px, 24vh, 260px);
    }
  }

  /* Reduced motion — stop marquee, keep cards browsable */
  @media (prefers-reduced-motion: reduce) {
    .works-rev-inner { opacity: 1 !important; transform: none !important; transition: none !important; }
    .works-rev-track { animation: none !important; }
    .works-rev-marquee { overflow-x: auto; }
    .works-rev-panel { animation: none !important; }
  }
`;
document.head.appendChild(worksRevStyle);

window.CoviaWorks = CoviaWorks;
