// Portfolio + Review detail views — hash-based routing + image gallery + rich text

function useHashRoute() {
  const [hash, setHash] = React.useState(() => window.location.hash || "");
  React.useEffect(() => {
    const onChange = () => setHash(window.location.hash || "");
    window.addEventListener("hashchange", onChange);
    return () => window.removeEventListener("hashchange", onChange);
  }, []);
  return hash;
}

function parseRoute(hash) {
  const m = hash.match(/^#\/(portfolio|review)\/([^/?#]+)$/);
  if (!m) return null;
  return { type: m[1], id: decodeURIComponent(m[2]) };
}

function closeDetail() {
  if (window.location.hash) {
    if (window.history.length > 1) window.history.back();
    else window.location.hash = "";
  }
}

function DetailRouter() {
  const hash = useHashRoute();
  const route = parseRoute(hash);
  const open = !!route;

  React.useEffect(() => {
    if (open) {
      document.body.style.overflow = "hidden";
      document.body.classList.add("detail-open");
    } else {
      document.body.style.overflow = "";
      document.body.classList.remove("detail-open");
    }
    return () => {
      document.body.style.overflow = "";
      document.body.classList.remove("detail-open");
    };
  }, [open]);

  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === "Escape") closeDetail(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open]);

  // Scroll to top on detail open / route change
  React.useEffect(() => {
    if (open) window.scrollTo(0, 0);
  }, [hash, open]);

  if (!route) return null;
  if (route.type === "portfolio") return <PortfolioDetail id={route.id}/>;
  if (route.type === "review")    return <ReviewDetail    id={route.id}/>;
  return null;
}

function DetailFrame({ children, eyebrow }) {
  return (
    <div className="vl-detail">
      <header className="vl-detail-bar">
        <div className="container vl-detail-bar-inner">
          <button className="vl-detail-back" onClick={closeDetail} aria-label="뒤로가기">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" style={{width:18,height:18}}>
              <path d="M19 12H5M12 19l-7-7 7-7"/>
            </svg>
            <span>목록으로</span>
          </button>
          {eyebrow && <span className="vl-detail-eyebrow">{eyebrow}</span>}
          <button className="vl-detail-close" onClick={closeDetail} aria-label="닫기">×</button>
        </div>
      </header>
      <main className="vl-detail-body">{children}</main>
    </div>
  );
}

// Detect video URL type
function parseVideoUrl(url) {
  if (!url) return null;
  const u = String(url).trim();
  let m = u.match(/(?:youtube\.com\/(?:watch\?v=|embed\/|v\/|shorts\/)|youtu\.be\/)([A-Za-z0-9_-]{11})/);
  if (m) return { type: "youtube", id: m[1] };
  m = u.match(/vimeo\.com\/(?:video\/)?(\d+)/);
  if (m) return { type: "vimeo", id: m[1] };
  return null;
}

// Build mixed media items: images first (as type:'image'), then videos
function buildMedia(imgs, videos) {
  const items = [];
  (imgs || []).forEach(url => { if (url) items.push({ kind: "image", url }); });
  (videos || []).forEach(url => {
    if (!url) return;
    const parsed = parseVideoUrl(url);
    if (parsed) items.push({ kind: parsed.type, id: parsed.id, url });
    else items.push({ kind: "video", url });
  });
  return items;
}

function MediaThumb({ item }) {
  if (item.kind === "image") return <img src={item.url} alt=""/>;
  if (item.kind === "youtube") return <img src={`https://img.youtube.com/vi/${item.id}/mqdefault.jpg`} alt=""/>;
  return (
    <div style={{width:"100%",height:"100%",background:"#000",display:"flex",alignItems:"center",justifyContent:"center",color:"var(--gold)"}}>
      <svg viewBox="0 0 24 24" fill="currentColor" style={{width:22,height:22,marginLeft:3}}><path d="M8 5v14l11-7z"/></svg>
    </div>
  );
}

function MediaMain({ item, alt }) {
  if (item.kind === "image") {
    return <img src={item.url} alt={alt} onError={(e) => { e.target.style.background = "var(--surface)"; }}/>;
  }
  if (item.kind === "youtube") {
    return (
      <iframe
        src={`https://www.youtube.com/embed/${item.id}?rel=0&modestbranding=1`}
        title={alt || "video"}
        frameBorder="0"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
        allowFullScreen
        style={{width:"100%",height:"100%",border:0,background:"#000"}}
      />
    );
  }
  if (item.kind === "vimeo") {
    return (
      <iframe
        src={`https://player.vimeo.com/video/${item.id}`}
        title={alt || "video"}
        frameBorder="0"
        allow="autoplay; fullscreen; picture-in-picture"
        allowFullScreen
        style={{width:"100%",height:"100%",border:0,background:"#000"}}
      />
    );
  }
  // uploaded video
  return (
    <video src={item.url} controls preload="metadata"
      style={{width:"100%",height:"100%",objectFit:"contain",background:"#000",display:"block"}}/>
  );
}

// ====== Media Gallery with main view + thumbnails (images + videos) ======
function ImageGallery({ imgs, videos, alt }) {
  // Backward compat: if called with imgs only, treat empty videos
  const items = buildMedia(imgs, videos || []);
  const [idx, setIdx] = React.useState(0);
  if (items.length === 0) return null;
  const safe = Math.min(idx, items.length - 1);
  const go = (next) => setIdx((next + items.length) % items.length);
  const current = items[safe];

  return (
    <div className="vl-gallery">
      <div className="vl-gallery-main">
        <MediaMain item={current} alt={alt}/>
        {items.length > 1 && (
          <React.Fragment>
            <button className="vl-gallery-arrow vl-gallery-prev" onClick={() => go(safe - 1)} aria-label="이전">‹</button>
            <button className="vl-gallery-arrow vl-gallery-next" onClick={() => go(safe + 1)} aria-label="다음">›</button>
            <div className="vl-gallery-count">{safe + 1} / {items.length}</div>
          </React.Fragment>
        )}
      </div>
      {items.length > 1 && (
        <div className="vl-gallery-thumbs">
          {items.map((it, i) => (
            <button key={i} className={"vl-gallery-thumb" + (i === safe ? " active" : "") + (it.kind !== "image" ? " is-video" : "")} onClick={() => setIdx(i)}>
              <MediaThumb item={it}/>
              {it.kind !== "image" && (
                <span className="vl-gallery-thumb-play">
                  <svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
                </span>
              )}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

function PortfolioDetail({ id }) {
  const [item, setItem] = React.useState(null);
  const [notFound, setNotFound] = React.useState(false);

  React.useEffect(() => {
    fetch("/api/portfolio")
      .then(r => r.json())
      .then(d => {
        const found = (d.list || []).find(p => p.id === id);
        if (found) setItem(found);
        else setNotFound(true);
      })
      .catch(() => setNotFound(true));
  }, [id]);

  if (notFound) {
    return (
      <DetailFrame eyebrow="PORTFOLIO">
        <div className="container vl-detail-empty">
          <p>작품을 찾을 수 없습니다.</p>
          <button className="cta-btn" onClick={closeDetail}>목록으로 돌아가기</button>
        </div>
      </DetailFrame>
    );
  }
  if (!item) {
    return (
      <DetailFrame eyebrow="PORTFOLIO">
        <div className="container vl-detail-loading">불러오는 중...</div>
      </DetailFrame>
    );
  }

  const allImgs = [item.img, ...(Array.isArray(item.imgs) ? item.imgs : [])].filter(Boolean);

  return (
    <DetailFrame eyebrow={"PORTFOLIO · " + (item.cat || "")}>
      <div className="container vl-product">
        <div className="vl-product-grid">
          <div className="vl-product-img-col">
            <ImageGallery imgs={allImgs} videos={Array.isArray(item.videos) ? item.videos : []} alt={item.title}/>
          </div>
          <div className="vl-product-info">
            <div className="vl-product-case">VELOEN · CASE {item.caseNo || ""}</div>
            <h1 className="vl-product-title">{item.title}</h1>
            <div className="vl-product-cat-row">
              <span className="vl-product-cat">{item.cat}</span>
            </div>
            {item.description ? (
              <div className="vl-product-desc vl-rich" dangerouslySetInnerHTML={{ __html: item.description }}/>
            ) : (
              <div className="vl-product-desc vl-product-desc-empty">
                이 작품에 대한 상세 설명을 준비 중입니다.<br/>
                자세한 사항이 궁금하시면 카카오톡으로 문의해주세요.
              </div>
            )}
            <div className="vl-product-cta">
              <button className="cta-btn" onClick={() => window.dispatchEvent(new CustomEvent("open-inquiry"))}>
                이 제품 문의하기 →
              </button>
            </div>
          </div>
        </div>
      </div>
    </DetailFrame>
  );
}

function ReviewDetail({ id }) {
  const [item, setItem] = React.useState(null);
  const [notFound, setNotFound] = React.useState(false);

  React.useEffect(() => {
    fetch("/api/reviews")
      .then(r => r.json())
      .then(d => {
        const found = (d.list || []).find(r => r.id === id);
        if (found) setItem(found);
        else setNotFound(true);
      })
      .catch(() => setNotFound(true));
  }, [id]);

  if (notFound) {
    return (
      <DetailFrame eyebrow="CUSTOMER REVIEW">
        <div className="container vl-detail-empty">
          <p>후기를 찾을 수 없습니다.</p>
          <button className="cta-btn" onClick={closeDetail}>목록으로 돌아가기</button>
        </div>
      </DetailFrame>
    );
  }
  if (!item) {
    return (
      <DetailFrame eyebrow="CUSTOMER REVIEW">
        <div className="container vl-detail-loading">불러오는 중...</div>
      </DetailFrame>
    );
  }

  const stars = "★★★★★".slice(0, item.stars || 5);
  const date = item.createdAt ? new Date(item.createdAt).toLocaleDateString("ko-KR") : "";
  const allImgs = [item.img, ...(Array.isArray(item.imgs) ? item.imgs : [])].filter(Boolean);
  const bodyLooksHtml = item.body && /<[a-z][\s\S]*>/i.test(item.body);

  return (
    <DetailFrame eyebrow="CUSTOMER REVIEW">
      <div className="container vl-review-detail">
        {(allImgs.length > 0 || (Array.isArray(item.videos) && item.videos.length > 0)) && (
          <div className="vl-review-gallery-wrap">
            <ImageGallery imgs={allImgs} videos={Array.isArray(item.videos) ? item.videos : []} alt=""/>
          </div>
        )}
        <div className="vl-review-stars">{stars}</div>
        {item.quote && <h1 className="vl-review-quote">{item.quote}</h1>}
        {item.body && (
          bodyLooksHtml
            ? <div className="vl-review-body vl-rich" dangerouslySetInnerHTML={{ __html: item.body }}/>
            : <div className="vl-review-body">{item.body.split("\n").map((line, i) => <p key={i}>{line || " "}</p>)}</div>
        )}
        <div className="vl-review-meta-row">
          {item.author && <span>{item.author}</span>}
          {item.product && <span>· {item.product}</span>}
          {date && <span>· {date}</span>}
        </div>
        <div className="vl-review-cta">
          <button className="cta-btn" onClick={() => window.dispatchEvent(new CustomEvent("open-inquiry"))}>
            나도 제작 문의하기 →
          </button>
        </div>
      </div>
    </DetailFrame>
  );
}

window.DetailRouter = DetailRouter;
