/* Denky — 상품 상세 */

/* 상세 페이지 찜(하트) 버튼 — 카드의 하트와 같은 찜 캐시(API._wishIds)를 씁니다 */
function DetailWishBtn({ p }) {
  const [wished, setWished] = useState(API.wishHas(p.id));
  async function onHeart() {
    const t = window.denkyToast;
    try {
      const r = await API.toggleWish(p.id);
      if (r === "login") { if (t) t("로그인하면 찜할 수 있어요"); return; }
      setWished(r === "added");
      if (t) t(r === "added" ? "찜했어요" : "찜을 해제했어요");
    } catch (err) {
      if (t) t(err.message || "잠시 후 다시 시도해 주세요");
    }
  }
  return (
    <button type="button" onClick={onHeart} aria-label="찜"
      style={{
        width: 54, flex: "none", borderRadius: 12, border: "1px solid var(--border)", cursor: "pointer",
        background: "var(--surface)", display: "grid", placeItems: "center",
        color: wished ? "#E11D48" : "var(--sub)", transition: "color .14s",
      }}>
      <Icon name="heart" size={20} fill={wished ? "currentColor" : "none"} />
    </button>
  );
}

function DetailScreen({ p: pIn, go, openProduct, tryProduct, addToCart, startCheckout, t, auth }) {
  const [active, setActive] = useState(0);
  const [zoom, setZoom] = useState(false);
  const [tab, setTab] = useState(null);   // 상품정보 / 리뷰 / 문의 탭 — 기본은 셋 다 접힘(null)
  const [reviewData, setReviewData] = useState(null);   // {summary, items}
  const [inquiryData, setInquiryData] = useState(null); // {items}
  const [revForm, setRevForm] = useState({ rating: 5, content: "", image: "" });
  const [inqForm, setInqForm] = useState({ content: "", is_secret: false });
  const [note, setNote] = useState("");     // 인라인 안내 메시지
  const [opts, setOpts] = useState({});     // 선택한 옵션 {색상, 사이즈, ...}
  const [infoOpen, setInfoOpen] = useState(false);  // 상품정보 제공 고시 — 평상시 숨김(더보기)
  const [descOpen, setDescOpen] = useState(false);  // 상세페이지 — 기본 접힘(펼쳐보기)
  // 상세는 상품 id 로 '전체 정보'를 다시 불러와, 부분 객체(장바구니·착장 등)나 오래된 데이터를 보완합니다.
  // 넘어온 pIn 은 즉시 표시용 자리표시자 — 로드되면 full 로 대체돼 옵션·갤러리·리뷰수까지 채워집니다.
  const [full, setFull] = useState(null);        // API 로 다시 불러온 전체 상품 (null=아직/실패)
  const [notFound, setNotFound] = useState(false); // 삭제·판매종료로 못 불러온 경우
  const p = full || pIn;

  const pid = pIn ? pIn.id : (full ? full.id : null);

  // 상품 전체정보 재조회 — 부분 객체로 열려도 상세가 온전히 뜨도록. (id 없으면 스킵)
  useEffect(() => {
    if (!pid) return;
    let alive = true;
    setNotFound(false);
    API.product(pid)
      .then((r) => { if (alive) setFull(API.normalize(r)); })
      .catch(() => { if (alive && !pIn) setNotFound(true); }); // 넘어온 데이터도 없고 조회도 실패 → 안내
    return () => { alive = false; };
  }, [pid]);

  // 사이즈 추천 요약 카드 — 상세 첫 화면에서 "나에게 맞나"를 바로 답한다 (스마트앱과 동일 기획).
  // 사이즈표 있는 상품 + 로그인 회원이면 추천을 미리 불러오고, 펼치면 착용선호 토글·분석 요약.
  const [sizeReco, setSizeReco] = useState(null);
  const [sizeLoading, setSizeLoading] = useState(false);
  const [sizeOpen, setSizeOpen] = useState(false);  // 기본 '접힘'(스마트앱과 동일) — 요약 한 줄, 탭하면 전체 분석
  // 사이즈 안내를 보여줄 상품인가 — 실측 사이즈표가 있거나, 주문 옵션에 사이즈 축이 있으면 보여준다.
  // (사이즈표가 없어도 옵션 사이즈만으로 '살 수 있는 사이즈 중' 추천을 해 준다.
  //  둘 다 없으면 고를 사이즈 자체가 없는 상품이라 카드를 띄우지 않는다)
  const hasSizeInfo = !!(p && (p.sizeChart || Object.keys(p.options || {}).some((axis) =>
    axis.includes("사이즈") || axis.includes("싸이즈") || axis.toLowerCase().includes("size"))));
  useEffect(() => {
    if (!pid || !auth || !auth.loggedIn || !hasSizeInfo) { setSizeReco(null); return; }
    let alive = true;
    setSizeLoading(true);
    API.sizeRecommendation(pid)
      .then((r) => { if (alive) { setSizeReco(r); setSizeLoading(false); } })
      .catch(() => { if (alive) { setSizeReco(null); setSizeLoading(false); } });
    return () => { alive = false; };
  }, [pid, auth && auth.loggedIn, hasSizeInfo]);

  // '이 옷과 어울리는 코디' — AI 코디네이터(앵커=이 상품). 로그인 회원만(체형·사이즈에 회원 정보 필요).
  const [coordiItems, setCoordiItems] = useState([]);
  useEffect(() => {
    if (!pid || !auth || !auth.loggedIn) { setCoordiItems([]); return; }
    let alive = true;
    API.coordinatorRecommend({ anchorProductId: pid })
      .then((items) => { if (alive) setCoordiItems(items || []); })
      .catch(() => {});   // 실패는 조용히 — 섹션만 안 뜬다
    return () => { alive = false; };
  }, [pid, auth && auth.loggedIn]);
  // 이 상품이 고르게 하는 옵션 축들 (값 있는 것만). 없으면 옵션 없는 상품.
  const optionAxes = (p && p.options)
    ? Object.entries(p.options).filter(([, v]) => Array.isArray(v) && v.length)
    : [];
  const allSelected = optionAxes.every(([axis]) => opts[axis]);
  // 옵션을 다 골랐는지 확인하고 fn(p, 선택옵션) 을 호출. 안 골랐으면 안내.
  function withOptions(fn) {
    if (optionAxes.length && !allSelected) {
      setNote(`${optionAxes.map(([a]) => a).join("·")} 옵션을 선택해 주세요.`);
      return;
    }
    fn(p, optionAxes.length ? opts : undefined);
  }

  // 가상피팅 시작 — 옵션 미선택·품절을 통제하고, 팔면 그 색으로 피팅한다.
  //  ★피팅 버튼은 화면 위쪽이라 인라인 note 가 안 보인다 → 전역 토스트(window.denkyToast)로 안내.★
  //  (t 는 설정 객체라 함수 아님 — toast 는 app.jsx 가 window.denkyToast 로 노출. 위탁은 도매꾹 실시간 조합재고)
  async function startFit() {
    const toast = window.denkyToast || (() => {});
    // 피팅 미지원 상품(상세에 온전한 옷 컷 없음 판정) — 버튼도 잠그지만 이중 방어.
    if (p.fitting_supported === false) {
      toast("이 상품은 상세 이미지에 온전한 옷 컷이 없어 가상피팅을 지원하지 않아요");
      return;
    }
    if (optionAxes.length && !allSelected) {
      toast(`${optionAxes.map(([a]) => a).join("·")} 옵션을 먼저 선택해 주세요`);
      return;
    }
    const vals = optionAxes.length ? Object.values(opts).filter(Boolean) : [];
    if (vals.length) {
      try {
        const ok = await API.optionInStock(p.id, vals);
        if (!ok) { toast("선택하신 옵션은 품절이에요"); return; }
      } catch (_) { /* 재고 확인 실패(네트워크 등)면 막지 않고 진행 */ }
    }
    // 고른 옵션(색+사이즈)을 맵째로 넘김 — 색은 대표컷+HEX 렌더, 카드 표시, 결과 페이지 담기/구매에도 그대로 재사용.
    const optMap = {};
    optionAxes.forEach(([a]) => { if (opts[a]) optMap[a] = opts[a]; });
    tryProduct(p, Object.keys(optMap).length ? optMap : undefined);
  }

  // 리뷰/문의 데이터 로드 (실패해도 빈 상태로 두어 화면이 깨지지 않게)
  useEffect(() => {
    setNote("");
    setTab(null);
    setActive(0);
    setOpts({});  // 상품이 바뀌면 옵션 선택 초기화
    if (!pid) { setReviewData(null); setInquiryData(null); return; }
    let alive = true;
    API.reviews(pid).then((d) => { if (alive) setReviewData(d); })
      .catch(() => { if (alive) setReviewData({ summary: { count: 0, average: 0, distribution: {} }, items: [] }); });
    API.inquiries(pid).then((d) => { if (alive) setInquiryData(d); })
      .catch(() => { if (alive) setInquiryData({ items: [] }); });
    return () => { alive = false; };
  }, [pid]);

  // 상품이 아예 없으면(직접 진입·삭제 등) 빈 화면 대신 안내 — '상세페이지가 안 보이는' 문제 방지.
  if (!p) {
    return (
      <div className="page wrap" style={{ paddingTop: 80, paddingBottom: 80, textAlign: "center" }}>
        <div className="ill" style={{ display: "inline-flex", marginBottom: 16 }}><Icon name="bag" size={44} stroke={1.4} /></div>
        <h2 className="t-h2" style={{ margin: "0 0 8px" }}>{notFound ? "판매 종료된 상품이에요" : "상품을 불러올 수 없어요"}</h2>
        <p className="t-body t-sub" style={{ margin: "0 0 24px" }}>다른 상품을 둘러보세요.</p>
        <Btn variant="primary" onClick={() => go("catalog")}>쇼핑 계속하기</Btn>
      </div>
    );
  }

  // 리뷰 등록
  async function submitReview() {
    setNote("");
    try {
      await API.createReview(p.id, {
        rating: revForm.rating,
        content: revForm.content.trim() || null,
        image_url: revForm.image || null,
      });
      setRevForm({ rating: 5, content: "", image: "" });
      setReviewData(await API.reviews(p.id));
      setNote("리뷰가 등록됐어요. 감사합니다!");
    } catch (e) {
      if (e.status === 401) { go("login"); return; }
      setNote(e.message || "리뷰를 등록하지 못했어요.");
    }
  }
  // 문의 등록
  async function submitInquiry() {
    setNote("");
    if (!inqForm.content.trim()) { setNote("문의 내용을 입력해 주세요."); return; }
    try {
      await API.createInquiry(p.id, { content: inqForm.content.trim(), is_secret: inqForm.is_secret });
      setInqForm({ content: "", is_secret: false });
      setInquiryData(await API.inquiries(p.id));
      setNote("문의가 등록됐어요.");
    } catch (e) {
      if (e.status === 401) { go("login"); return; }
      setNote(e.message || "문의를 등록하지 못했어요.");
    }
  }
  // 판매자가 올린 상세 이미지들(세로로 전체 노출). 대표 1장뿐이면 상세 섹션은 생략합니다.
  const detailImages = (p.images && p.images.length ? p.images : []).filter(Boolean);
  // 이미지 갤러리 — 여러 장이면 썸네일로 전환합니다.
  const gallery = (p.images && p.images.length ? p.images : (p.image ? [p.image] : []));
  const mainImage = gallery[active] || p.image;
  // (예전 '비슷한 상품'(목데이터)은 제거 — 필터로 들어온 사용자에겐 중복이라, AI 코디 섹션으로 대체)

  return (
    <div className="page wrap" style={{ paddingTop: 28, paddingBottom: 48 }}>
      {/* 뒤로가기 + breadcrumb — 뒤로가기는 직전 화면(카테고리 필터·목록 위치 그대로)으로 복원 */}
      <div className="row" style={{ gap: 12, marginBottom: 24, alignItems: "center" }}>
        <BackBtn style={{ width: 36, height: 36 }} />
        <div className="row t-small t-sub" style={{ gap: 6 }}>
          <a href="#" onClick={(e) => { e.preventDefault(); go("home"); }}>홈</a>
          <Icon name="chevR" size={13} />
          <a href="#" onClick={(e) => { e.preventDefault(); go("catalog", { type: p.type }); }}>{p.type}</a>
          <Icon name="chevR" size={13} />
          <span style={{ color: "var(--ink)" }}>{p.name}</span>
        </div>
      </div>

      <div className="detail-grid">
        {/* 이미지 */}
        <div className="detail-sticky">
          <div className="card" style={{ aspectRatio: "3/4", borderRadius: 20, cursor: "zoom-in", overflow: "hidden", maxWidth: "80%", margin: "0 auto" }} onClick={() => setZoom(true)}>
            {mainImage
              ? <img src={mainImage} alt={p.name} style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }} />
              : <PhImg tone={p.tone} ink={p.toneInk} type={p.type} label={`${p.type} · 대표 이미지 (클릭 확대)`} />}
          </div>
          {/* 여러 장이면 썸네일 갤러리로 전환 */}
          {gallery.length > 1 && (
            <div className="row" style={{ gap: 10, marginTop: 12, flexWrap: "wrap" }}>
              {gallery.map((src, i) => (
                <button key={i} onClick={() => setActive(i)} className="thumb"
                  style={{ width: 52, height: 66, borderRadius: 9, overflow: "hidden", padding: 0, background: "none", cursor: "pointer",
                           border: i === active ? "2px solid var(--primary)" : "1px solid var(--border)" }}>
                  <img src={src} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} />
                </button>
              ))}
            </div>
          )}
          {/* 상품명·가격 — 썸네일 바로 아래(사용자 결정: 좌측=상품 아이덴티티, 우측=분석·옵션·구매) */}
          <div style={{ maxWidth: "80%", margin: "18px auto 0" }}>
            <p className="brand" style={{ color: "var(--sub)", fontSize: 13, margin: "0 0 7px", fontWeight: 600 }}>{p.brand}</p>
            {/* 상품명·가격 — 썸네일 아래라 크게 강조할 필요 없어 폰트 축소(t-h1 기본 32px→21px) */}
            <h1 className="t-h1" style={{ margin: "0 0 10px", fontSize: 21, lineHeight: "29px" }}>{p.name}</h1>
            <div className="row" style={{ gap: 14, marginBottom: 12 }}>
              <Rating value={p.rating != null ? p.rating : "신규"} count={p.reviews} size={15} />
              {p.popular && <Chip soft>인기 상품</Chip>}
            </div>
            <PriceTag price={p.price} discount={p.discountPrice} />
          </div>
        </div>

        {/* 정보(우측) — 사이즈·체형 분석(전체 펼침) + 옵션 + 구매 */}
        <div>
          {/* 사이즈 추천 요약 카드 — 우측 최상단에서 "나에게 맞나"를 답한다.
              (사이즈표가 없어도 옵션에 사이즈가 있으면 그 안에서 추천한다) */}
          {hasSizeInfo && (
            <div style={{ background: "var(--surface)", border: "1px solid var(--border)",
                          borderRadius: 14, overflow: "hidden" }}>
              <button
                onClick={() => {
                  if (!auth || !auth.loggedIn) { t("로그인하면 내 몸 기준 사이즈를 알려드려요"); go("login"); return; }
                  setSizeOpen((v) => !v);
                }}
                style={{ display: "flex", alignItems: "center", gap: 11, width: "100%", padding: "12px 14px",
                         background: "none", border: 0, cursor: "pointer", textAlign: "left", fontFamily: "inherit" }}>
                <span style={{ width: 34, height: 34, borderRadius: 10, background: "linear-gradient(135deg, #4AA6FF, #1E78EF)",
                               display: "inline-flex", alignItems: "center", justifyContent: "center", flex: "none" }}>
                  <Icon name="sparkle" size={17} style={{ color: "#fff" }} />
                </span>
                <span style={{ flex: 1, minWidth: 0 }}>
                  <span style={{ display: "block", fontSize: 13.5, fontWeight: 800, color: "var(--ink)",
                                 whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                    {!auth || !auth.loggedIn
                      ? "로그인하면 내 몸 기준 추천 사이즈를 알려드려요"
                      : (sizeLoading && !sizeReco) ? "내 사이즈 분석 중…"
                      : (sizeReco && sizeReco.available) ? `회원님 추천 사이즈 ${sizeReco.size_label || sizeReco.size}`
                      : ((sizeReco && sizeReco.message) || "신체정보를 입력하면 내 사이즈를 알려드려요")}
                  </span>
                  {sizeReco && sizeReco.available && (sizeReco.fit_note || sizeReco.reason) && (
                    <span style={{ display: "block", fontSize: 12, color: "var(--sub)", marginTop: 2,
                                   whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                      {sizeReco.fit_note || sizeReco.reason}
                    </span>
                  )}
                </span>
                <span style={{ color: "var(--sub)", fontSize: 13 }}>{sizeOpen ? "▲" : "▼"}</span>
              </button>
              {sizeOpen && auth && auth.loggedIn && (
                <div style={{ padding: "0 14px 14px" }}>
                  {/* 전체 사이즈·체형 분석 — 입어보기와 동일한 공용 패널(체형→추천사이즈+토글→부위별핏→사이즈표) */}
                  <SizeAnalysisPanel p={p} sizeReco={sizeReco} auth={auth} go={go} />
                </div>
              )}
            </div>
          )}

          <hr className="divider" style={{ margin: "24px 0" }} />

          {/* 옵션 선택 — 도매꾹 스타일 드롭다운. 옵션 축 수는 상품마다 다름(동적). 앞 옵션을 골라야 다음이 열림(순차). */}
          {optionAxes.map(([axis, values], idx) => {
            const prevDone = idx === 0 || optionAxes.slice(0, idx).every(([a]) => opts[a]);
            return (
              <div key={axis} style={{ marginBottom: 10 }}>
                <select value={opts[axis] || ""} disabled={!prevDone}
                  onChange={(e) => { setOpts((o) => ({ ...o, [axis]: e.target.value })); setNote(""); }}
                  style={{ width: "100%", padding: "13px 14px", borderRadius: 10, fontSize: 14, fontFamily: "inherit",
                    border: opts[axis] ? "1.5px solid var(--primary)" : "1px solid #D1D5DB",
                    background: prevDone ? "#fff" : "#F3F4F6",
                    color: opts[axis] ? "var(--ink)" : "var(--sub)", cursor: prevDone ? "pointer" : "not-allowed" }}>
                  <option value="" disabled>{axis} 선택{!prevDone ? " · 앞 옵션 먼저" : ""}</option>
                  {values.map((v) => <option key={v} value={v}>{v}</option>)}
                </select>
              </div>
            );
          })}
          {optionAxes.length > 0 && allSelected && (
            <div style={{ background: "var(--surface)", borderRadius: 10, padding: "11px 14px", margin: "4px 0 16px", display: "flex", justifyContent: "space-between", alignItems: "center", gap: 10 }}>
              <span style={{ fontSize: 13.5, fontWeight: 600 }}>{optionAxes.map(([a]) => opts[a]).join(" / ")}</span>
              <button onClick={() => setOpts({})} aria-label="옵션 초기화"
                style={{ background: "none", border: 0, color: "var(--sub)", cursor: "pointer", fontSize: 17, lineHeight: 1, padding: 0 }}>✕</button>
            </div>
          )}

          {/* 핵심 CTA — 모든 상품은 앱 내 장바구니/결제입니다. */}
          <div className="stack" style={{ gap: 12 }}>
            {p.fitting_supported === false ? (
              /* 피팅 미지원(온전한 옷 컷 없음 판정) — 썸네일 억지 렌더 대신 이유를 안내한다 */
              <Btn variant="outline" size="lg" block disabled style={{ opacity: 0.55, cursor: "not-allowed" }}
                title="이 상품은 상세 이미지에 온전한 옷 컷이 없어 가상피팅을 지원하지 않아요">
                가상피팅 미지원 상품이에요
              </Btn>
            ) : (
              <Btn variant="primary" size="lg" block icon="sparkle" onClick={startFit}>가상피팅으로 입어보기</Btn>
            )}
            <div className="row" style={{ gap: 12 }}>
              <Btn variant="outline" size="lg" block icon="cart" onClick={() => withOptions(addToCart)} style={{ flex: 1 }}>장바구니</Btn>
              <Btn variant="dark" size="lg" block iconR="arrowR" onClick={() => withOptions(startCheckout)} style={{ flex: 1 }}>구매하기</Btn>
            </div>
            <p className="t-caption t-sub row" style={{ gap: 6, justifyContent: "center", marginTop: 4 }}>
              <Icon name="shield" size={14} />
              앱에서 바로 주문 · 안심 결제
            </p>
          </div>
        </div>
      </div>

      {/* 상품정보 / 리뷰 / 문의 — 에이블리 스타일 탭 섹션 */}
      <section style={{ margin: "64px auto 0", maxWidth: 820 }}>
        {/* 탭 바 */}
        <div className="row" style={{ borderBottom: "1px solid var(--border)" }}>
          {[["info", "상품정보"], ["review", `리뷰 ${p.reviews || 0}`], ["qna", "문의"]].map(([key, label]) => (
            <button key={key} onClick={() => setTab(tab === key ? null : key)} style={{
              flex: 1, padding: "16px 0", background: "none", border: 0, cursor: "pointer", fontSize: 15,
              fontWeight: tab === key ? 800 : 600, color: tab === key ? "var(--ink)" : "var(--sub)",
              borderBottom: tab === key ? "2px solid var(--ink)" : "2px solid transparent", marginBottom: -1,
            }}>{label}</button>
          ))}
        </div>

        <div style={{ paddingTop: 28 }}>
          {/* ── 상품정보 ── */}
          {tab === "info" && (
            <div>
              {p.productInfo && Object.keys(p.productInfo).length > 0 && (
                <div className="card" style={{ padding: "2px 20px", marginBottom: 24 }}>
                  <button onClick={() => setInfoOpen((v) => !v)}
                    style={{ width: "100%", padding: "14px 0", background: "none", border: 0, cursor: "pointer", display: "flex", justifyContent: "space-between", alignItems: "center", fontWeight: 700, fontSize: 14, color: "var(--ink)", fontFamily: "inherit" }}>
                    상품정보 제공 고시 <span style={{ color: "var(--sub)", fontSize: 13, fontWeight: 500 }}>{infoOpen ? "접기 ▲" : "더보기 ▼"}</span>
                  </button>
                  {infoOpen && Object.entries(p.productInfo).map(([k, v]) => (
                    <div key={k} className="row" style={{ gap: 16, padding: "11px 0", borderTop: "1px solid var(--border)" }}>
                      <span style={{ width: 112, flex: "none", color: "var(--sub)", fontSize: 13.5 }}>{k}</span>
                      <span style={{ fontSize: 13.5, color: "var(--ink)" }}>{v}</span>
                    </div>
                  ))}
                </div>
              )}
              {p.description && (
                <p className="t-body" style={{ whiteSpace: "pre-wrap", color: "var(--sub)", lineHeight: 1.7, margin: "0 0 24px" }}>{p.description}</p>
              )}
              {!p.description && (!p.productInfo || !Object.keys(p.productInfo).length) && (
                <p className="t-small t-sub" style={{ textAlign: "center", padding: "24px 0" }}>등록된 상세 정보가 없어요.</p>
              )}
            </div>
          )}

          {/* ── 리뷰 ── */}
          {tab === "review" && (
            (() => {
              const s = (reviewData && reviewData.summary) || { count: 0, average: 0, distribution: {} };
              const dist = s.distribution || {};
              const maxC = Math.max(1, ...[5, 4, 3, 2, 1].map((k) => dist[k] || 0));
              const avg = s.average ? Number(s.average).toFixed(1) : "0.0";
              const items = (reviewData && reviewData.items) || [];
              return (
                <div>
                  {/* 평점 요약 + 별점 분포 (에이블리 스타일) */}
                  <div className="card" style={{ padding: 24, display: "flex", gap: 28, alignItems: "center", marginBottom: 20, flexWrap: "wrap" }}>
                    <div style={{ textAlign: "center", flex: "none" }}>
                      <div style={{ fontSize: 38, fontWeight: 800, lineHeight: 1 }}>{avg}</div>
                      <div style={{ marginTop: 6 }}><Rating value={avg} size={15} /></div>
                      <div className="t-small t-sub" style={{ marginTop: 4 }}>리뷰 {s.count}개</div>
                    </div>
                    <div style={{ flex: 1, minWidth: 200 }}>
                      {[5, 4, 3, 2, 1].map((star) => {
                        const c = dist[star] || 0;
                        return (
                          <div key={star} className="row" style={{ gap: 10, padding: "3px 0" }}>
                            <span style={{ width: 30, flex: "none", fontSize: 13, color: "var(--sub)" }}>{star}점</span>
                            <div style={{ flex: 1, height: 6, background: "var(--border)", borderRadius: 3, overflow: "hidden" }}>
                              <div style={{ width: (c / maxC * 100) + "%", height: "100%", background: "var(--primary)" }} />
                            </div>
                            <span className="t-small t-sub" style={{ width: 28, textAlign: "right" }}>{c}</span>
                          </div>
                        );
                      })}
                    </div>
                  </div>

                  {/* 작성 폼 */}
                  {API.loggedIn ? (
                    <div className="card" style={{ padding: 18, marginBottom: 20 }}>
                      <div className="row" style={{ gap: 6, alignItems: "center", marginBottom: 10 }}>
                        <span className="t-small t-sub" style={{ marginRight: 4 }}>별점</span>
                        {[1, 2, 3, 4, 5].map((n) => (
                          <button key={n} onClick={() => setRevForm((f) => ({ ...f, rating: n }))}
                            style={{ background: "none", border: 0, cursor: "pointer", padding: 0, lineHeight: 0, color: "var(--warn)" }}>
                            <Icon name="star" size={22} fill={n <= revForm.rating ? "var(--warn)" : "none"} stroke={n <= revForm.rating ? 0 : 1.6} />
                          </button>
                        ))}
                      </div>
                      <textarea className="input" style={{ width: "100%", minHeight: 70, padding: 10, resize: "vertical" }}
                        placeholder="이 상품 어떠셨나요? (구매한 상품만 작성할 수 있어요)"
                        value={revForm.content} onChange={(e) => setRevForm((f) => ({ ...f, content: e.target.value }))} />
                      <div className="row" style={{ justifyContent: "space-between", alignItems: "center", marginTop: 10 }}>
                        <div className="row" style={{ gap: 8, alignItems: "center" }}>
                          <label style={{ cursor: "pointer", fontSize: 13, color: "var(--primary)", border: "1px solid var(--primary)", borderRadius: 8, padding: "6px 12px" }}>
                            사진 첨부
                            <input type="file" accept="image/*" style={{ display: "none" }}
                              onChange={(e) => {
                                const f = e.target.files && e.target.files[0];
                                if (!f) return;
                                const rd = new FileReader();
                                rd.onload = () => setRevForm((x) => ({ ...x, image: rd.result }));
                                rd.readAsDataURL(f);
                              }} />
                          </label>
                          {revForm.image && (
                            <img src={revForm.image} alt="" style={{ width: 40, height: 40, objectFit: "cover", borderRadius: 6 }} />
                          )}
                        </div>
                        <Btn variant="primary" size="sm" onClick={submitReview}>리뷰 등록</Btn>
                      </div>
                    </div>
                  ) : (
                    <p className="t-small t-sub" style={{ marginBottom: 16 }}>
                      리뷰를 작성하려면 <a href="#" onClick={(e) => { e.preventDefault(); go("login"); }} style={{ color: "var(--primary)" }}>로그인</a> 해 주세요.
                    </p>
                  )}
                  {note && <div className="card" style={{ padding: "10px 14px", marginBottom: 16, background: "var(--accent-soft)", border: 0, color: "var(--primary-dark)" }}>{note}</div>}

                  {/* 리뷰 목록 */}
                  {items.length > 0 ? (
                    <div className="stack" style={{ gap: 14 }}>
                      {items.map((r) => (
                        <div key={r.id} className="card" style={{ padding: 16 }}>
                          <div className="row" style={{ justifyContent: "space-between", marginBottom: 6 }}>
                            <Rating value={r.rating} size={14} />
                            <span className="t-small t-sub">{r.author_name} · {(r.created_at || "").slice(0, 10)}</span>
                          </div>
                          {r.option_text && <div className="t-small t-sub" style={{ marginBottom: 4 }}>{r.option_text}</div>}
                          {r.content && <p className="t-body" style={{ margin: 0 }}>{r.content}</p>}
                          {r.image_url && <img src={r.image_url} alt="" style={{ marginTop: 10, maxWidth: 160, borderRadius: 8, display: "block" }} />}
                        </div>
                      ))}
                    </div>
                  ) : (
                    <div style={{ textAlign: "center", padding: "32px 0", color: "var(--sub)" }}>
                      <Icon name="star" size={30} stroke={1.5} />
                      <p className="t-body" style={{ margin: "8px 0 4px" }}>아직 등록된 리뷰가 없어요.</p>
                      <p className="t-small t-sub">가상피팅으로 입어보고 구매한 뒤 첫 리뷰를 남겨보세요.</p>
                    </div>
                  )}
                </div>
              );
            })()
          )}

          {/* ── 문의 ── */}
          {tab === "qna" && (() => {
            const items = (inquiryData && inquiryData.items) || [];
            return (
              <div>
                {/* 작성 폼 */}
                {API.loggedIn ? (
                  <div className="card" style={{ padding: 18, marginBottom: 20 }}>
                    <textarea className="input" style={{ width: "100%", minHeight: 64, padding: 10, resize: "vertical" }}
                      placeholder="상품에 궁금한 점을 남겨주세요. (영업일 기준 1~2일 내 답변)"
                      value={inqForm.content} onChange={(e) => setInqForm((f) => ({ ...f, content: e.target.value }))} />
                    <div className="row" style={{ justifyContent: "space-between", alignItems: "center", marginTop: 10 }}>
                      <label className="row t-small t-sub" style={{ gap: 6, cursor: "pointer" }}>
                        <input type="checkbox" checked={inqForm.is_secret} onChange={(e) => setInqForm((f) => ({ ...f, is_secret: e.target.checked }))} /> 비공개 문의
                      </label>
                      <Btn variant="primary" size="sm" onClick={submitInquiry}>문의 등록</Btn>
                    </div>
                  </div>
                ) : (
                  <p className="t-small t-sub" style={{ marginBottom: 16 }}>
                    문의를 작성하려면 <a href="#" onClick={(e) => { e.preventDefault(); go("login"); }} style={{ color: "var(--primary)" }}>로그인</a> 해 주세요.
                  </p>
                )}
                {note && <div className="card" style={{ padding: "10px 14px", marginBottom: 16, background: "var(--accent-soft)", border: 0, color: "var(--primary-dark)" }}>{note}</div>}

                {/* 문의 목록 */}
                {items.length > 0 ? (
                  <div className="stack" style={{ gap: 12 }}>
                    {items.map((q) => (
                      <div key={q.id} className="card" style={{ padding: 16 }}>
                        <div className="row" style={{ justifyContent: "space-between", marginBottom: 6, gap: 8, flexWrap: "wrap" }}>
                          <span className="row" style={{ gap: 6, alignItems: "center" }}>
                            <strong style={{ fontSize: 14 }}>Q</strong>
                            {q.is_secret && <Chip soft>비공개</Chip>}
                            {q.answered ? <Chip soft>답변완료</Chip> : <Chip outline>답변대기</Chip>}
                          </span>
                          <span className="t-small t-sub">{q.author_name} · {(q.created_at || "").slice(0, 10)}</span>
                        </div>
                        <p className="t-body" style={{ margin: 0 }}>{q.content || "비공개 문의예요."}</p>
                        {q.answer && (
                          <div style={{ marginTop: 10, padding: "10px 12px", background: "var(--surface)", borderRadius: 8 }}>
                            <strong style={{ fontSize: 13, color: "var(--primary-dark)" }}>A</strong>
                            <span className="t-body" style={{ marginLeft: 8 }}>{q.answer}</span>
                          </div>
                        )}
                      </div>
                    ))}
                  </div>
                ) : (
                  <div style={{ textAlign: "center", padding: "32px 0", color: "var(--sub)" }}>
                    <Icon name="user" size={30} stroke={1.5} />
                    <p className="t-body" style={{ marginTop: 8 }}>등록된 문의가 없어요.</p>
                  </div>
                )}
              </div>
            );
          })()}
        </div>
      </section>

      {/* 상세페이지 — 탭 아래에 썸네일(미리보기). '펼쳐보기'로 전체. */}
      {detailImages.length > 0 && (
        <section style={{ margin: "40px auto 0", maxWidth: 820 }}>
          <h2 className="t-h2" style={{ margin: "0 0 16px" }}>상세페이지</h2>
          <div className="stack" style={{ gap: 0, position: "relative", maxHeight: descOpen ? "none" : 460, overflow: "hidden" }}>
            {detailImages.map((src, i) => (
              <img key={i} src={src} alt={`상세 이미지 ${i + 1}`}
                style={{ width: "100%", display: "block", borderRadius: i === 0 ? 12 : 0 }} />
            ))}
            {!descOpen && <div style={{ position: "absolute", left: 0, right: 0, bottom: 0, height: 140, background: "linear-gradient(transparent, #fff)", pointerEvents: "none" }} />}
          </div>
          <button onClick={() => setDescOpen((v) => !v)}
            style={{ width: "100%", marginTop: 12, padding: "13px 0", borderRadius: 10, border: "1px solid var(--border)", background: "#fff", cursor: "pointer", fontWeight: 700, fontSize: 14, color: "var(--ink)", fontFamily: "inherit" }}>
            {descOpen ? "상세페이지 접기 ▲" : "상세페이지 펼쳐보기 ▼"}
          </button>
        </section>
      )}

      {/* 이 옷과 어울리는 코디 — AI 코디네이터(앵커=이 상품). 로그인+결과 있을 때만 노출.
          세트/설명 없이 어울리는 상품을 카탈로그 카드 그리드로 나열, 클릭 시 그 상품 상세로. */}
      {coordiItems.length > 0 && (
        <section style={{ marginTop: 80 }}>
          <div className="section-head">
            <div>
              <p className="eyebrow">AI STYLIST</p>
              <h2 className="t-h2">이 옷과 어울리는 코디</h2>
              {/* 소견서 정체성은 빼고, 추천 의상(어울림 문구) + 착장팁만 노출 */}
              {(() => {
                const b = p.styleBrief || {};
                const reco = [...(b.어울리는하의 || []), ...(b.어울리는상의 || []), ...(b.어울리는아우터 || [])];
                return reco.length > 0 ? (
                  <p className="t-small t-sub" style={{ margin: "6px 0 0" }}>추천: {reco.slice(0, 6).join(" · ")}</p>
                ) : null;
              })()}
              {p.styleBrief?.착장팁?.length > 0 && (
                <p className="t-small t-sub" style={{ margin: "4px 0 0", color: "var(--accent, #b8574a)" }}>
                  💡 {p.styleBrief.착장팁.join(" · ")}
                </p>
              )}
            </div>
          </div>
          <div className={t.gridCols === "3열" ? "grid-3" : "grid-catalog"}>
            {coordiItems.map((cp) => (
              <ProductCard key={cp.id} p={cp} onOpen={openProduct} onTry={tryProduct} showInfo={t.cardInfo} />
            ))}
          </div>
        </section>
      )}

      {/* zoom modal */}
      {zoom && (
        <div className="modal-scrim" onClick={() => setZoom(false)}>
          <div style={{ position: "relative", width: "min(560px,90vw)", animation: "popIn .24s var(--ease)" }} onClick={(e) => e.stopPropagation()}>
            <div className="card" style={{ aspectRatio: "3/4", borderRadius: 16, overflow: "hidden" }}>
              {mainImage
                ? <img src={mainImage} alt={p.name} style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }} />
                : <PhImg tone={p.tone} ink={p.toneInk} type={p.type} label="확대 이미지" />}
            </div>
            <button onClick={() => setZoom(false)} aria-label="닫기"
              style={{ position: "absolute", top: -14, right: -14, width: 40, height: 40, borderRadius: "50%", background: "#fff", border: 0, boxShadow: "var(--sh-2)", display: "grid", placeItems: "center" }}>
              <Icon name="close" size={18} />
            </button>
          </div>
        </div>
      )}
    </div>
  );
}
Object.assign(window, { DetailScreen });
