/* GoWithMe — Community UI primitives + Place Detail section.
   Reviews · History & Stories · Tips · Photos · Corrections.
   Loaded after ui.jsx/icons.jsx (T, Icon, Img, DISP, SANS, MONO are global). */

const fmtK = (n) => (n >= 1000 ? (n / 1000).toFixed(n >= 10000 ? 0 : 1).replace(/\.0$/, '') + 'k' : String(n));

/* ── display star row (supports fractional fill) ── */
function StarRow({ value, size = 16, gap = 2, color = T.gold, empty = '#ddceb2' }) {
  return (
    <div style={{ display: 'inline-flex', gap }}>
      {[0, 1, 2, 3, 4].map((i) => {
        const fill = Math.max(0, Math.min(1, value - i));
        return (
          <span key={i} style={{ position: 'relative', width: size, height: size, display: 'inline-block', lineHeight: 0 }}>
            <Icon name="star" size={size} color={empty} />
            {fill > 0 && (
              <span style={{ position: 'absolute', inset: 0, width: `${fill * 100}%`, overflow: 'hidden', lineHeight: 0 }}>
                <Icon name="star" size={size} color={color} />
              </span>
            )}
          </span>
        );
      })}
    </div>
  );
}

/* ── interactive star input (composer) ── */
function StarInput({ value, onChange, size = 42, gap = 8 }) {
  const [hover, setHover] = React.useState(0);
  const shown = hover || value;
  return (
    <div style={{ display: 'inline-flex', gap }} onMouseLeave={() => setHover(0)}>
      {[1, 2, 3, 4, 5].map((n) => (
        <button key={n} onMouseEnter={() => setHover(n)} onClick={() => onChange(n)} style={{
          background: 'none', border: 'none', padding: 0, cursor: 'pointer', lineHeight: 0,
        }}>
          <Icon name="star" size={size} color={n <= shown ? T.gold : '#ddceb2'} />
        </button>
      ))}
    </div>
  );
}

/* ── author avatar (photo · official · initials) ── */
function AuthorAvatar({ author, size = 42 }) {
  const r = { width: size, height: size, borderRadius: 999, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' };
  if (author.official) {
    return <div style={{ ...r, background: T.navy, border: `1.5px solid ${T.gold}` }}><Icon name="sparkle" size={size * 0.5} color={T.gold} /></div>;
  }
  if (author.photo) {
    return <div style={{ ...r, overflow: 'hidden', background: T.cream2 }}><img src={author.photo} alt={author.name} loading="lazy" decoding="async" style={{ width: '100%', height: '100%', objectFit: 'cover' }} /></div>;
  }
  return (
    <div style={{ ...r, background: author.color || T.navySoft, color: '#fff', fontFamily: SANS, fontWeight: 800, fontSize: size * 0.4, letterSpacing: 0.3 }}>
      {author.initials}
    </div>
  );
}

/* ── trust badge ── */
function TrustBadge({ kind }) {
  const map = {
    verified: { label: 'Verified visitor', icon: 'shield-check', color: T.teal, bg: T.tealBg },
    local:    { label: 'Local expert',     icon: 'map-pin',      color: T.goldDk, bg: T.goldBg },
    guide:    { label: 'Guide',            icon: 'award',        color: T.goldDk, bg: T.goldBg },
  };
  const b = map[kind]; if (!b) return null;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, padding: '3px 8px', borderRadius: 7, background: b.bg, color: b.color, fontFamily: SANS, fontWeight: 700, fontSize: 11 }}>
      <Icon name={b.icon} size={12} color={b.color} />{b.label}
    </span>
  );
}

/* ── contribution type pill ── */
function TypePill({ type, small }) {
  const c = HM.CTYPES[type]; if (!c) return null;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, padding: small ? '3px 9px' : '5px 11px', borderRadius: 8, background: c.bg, color: c.color, fontFamily: SANS, fontWeight: 700, fontSize: small ? 11.5 : 12.5 }}>
      <Icon name={c.icon} size={small ? 12 : 14} color={c.color} />{c.label}
    </span>
  );
}

/* ── AI learning status chip (the "we learn from your input" loop) ── */
function AIChip({ status }) {
  if (!status) return null;
  const map = {
    added:     { label: "Added to this place's AI guide", icon: 'sparkle', color: T.teal, bg: T.tealBg, solid: true },
    applied:   { label: 'Correction applied to the guide', icon: 'check', color: T.teal, bg: T.tealBg, solid: true },
    reviewing: { label: 'Being reviewed by GoWithMe AI', icon: 'bot', color: T.body, bg: T.cream2, solid: false },
  };
  const s = map[status]; if (!s) return null;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '5px 11px', borderRadius: 999, background: s.bg, color: s.color, fontFamily: SANS, fontWeight: 700, fontSize: 12 }}>
      <Icon name={s.icon} size={13} color={s.color} />{s.label}
    </span>
  );
}

/* ── sub-rating mini bars ── */
function SubRatings({ sub, cols = 3 }) {
  if (!sub) return null;
  return (
    <div style={{ display: 'grid', gridTemplateColumns: `repeat(${cols}, 1fr)`, gap: 12 }}>
      {HM.SUBRATINGS.map((s) => {
        const v = sub[s.key] || 0;
        return (
          <div key={s.key}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 5 }}>
              <span style={{ fontFamily: SANS, fontSize: 12.5, color: T.body, fontWeight: 600 }}>{s.label}</span>
              <span style={{ fontFamily: SANS, fontSize: 12.5, color: T.ink, fontWeight: 800 }}>{v.toFixed(1)}</span>
            </div>
            <div style={{ height: 5, borderRadius: 999, background: T.cream2, overflow: 'hidden' }}>
              <div style={{ width: `${(v / 5) * 100}%`, height: '100%', background: T.gold, borderRadius: 999 }} />
            </div>
          </div>
        );
      })}
    </div>
  );
}

/* ── rating distribution bars ── */
function DistBars({ dist, total }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      {[5, 4, 3, 2, 1].map((star) => {
        const n = dist[star] || 0;
        const pct = total ? (n / total) * 100 : 0;
        return (
          <div key={star} style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
            <span style={{ fontFamily: SANS, fontSize: 12, fontWeight: 700, color: T.body, width: 10, textAlign: 'right' }}>{star}</span>
            <Icon name="star" size={12} color={T.gold} />
            <div style={{ flex: 1, height: 7, borderRadius: 999, background: T.cream2, overflow: 'hidden' }}>
              <div style={{ width: `${pct}%`, height: '100%', background: star >= 4 ? T.gold : star === 3 ? '#d8b45e' : '#cbb892', borderRadius: 999 }} />
            </div>
            <span style={{ fontFamily: SANS, fontSize: 11.5, color: T.muted, width: 34, textAlign: 'right' }}>{fmtK(n)}</span>
          </div>
        );
      })}
    </div>
  );
}

/* ── rating summary (headline + dist + sub-ratings) ── */
function RatingSummary({ data, compact }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 18 }}>
        <div style={{ textAlign: 'center', flexShrink: 0 }}>
          <div style={{ fontFamily: DISP, fontWeight: 800, fontSize: 48, color: T.ink, lineHeight: 1 }}>{data.avg.toFixed(1)}</div>
          <div style={{ marginTop: 6 }}><StarRow value={data.avg} size={15} /></div>
          <div style={{ fontFamily: SANS, fontSize: 12.5, color: T.muted, marginTop: 5 }}>{fmtK(data.total)} ratings</div>
        </div>
        <div style={{ flex: 1, minWidth: 0 }}><DistBars dist={data.dist} total={data.total} /></div>
      </div>
      {!compact && data.sub && (
        <div style={{ borderTop: `1px solid ${T.line}`, paddingTop: 15 }}>
          <SubRatings sub={data.sub} />
        </div>
      )}
    </div>
  );
}

/* ── photo thumbnail ── */
function Photo({ p, size = 76, radius = 12, onClick }) {
  return <Img src={p.img} grad={p.grad || T.grad || GRAD_FALLBACK} radius={radius} onClick={onClick}
    style={{ width: size, height: size, flexShrink: 0, cursor: onClick ? 'pointer' : 'default' }} />;
}
const GRAD_FALLBACK = 'linear-gradient(150deg,#3a3530,#9a8666)';

/* ── expandable body text ── */
function ClampText({ text, lines = 4 }) {
  const [open, setOpen] = React.useState(false);
  const long = text.length > 220;
  return (
    <div>
      <p style={{
        fontFamily: SANS, fontSize: 14.5, lineHeight: 1.6, color: T.body, margin: 0, textWrap: 'pretty',
        ...(open || !long ? {} : { display: '-webkit-box', WebkitLineClamp: lines, WebkitBoxOrient: 'vertical', overflow: 'hidden' }),
      }}>{text}</p>
      {long && (
        <button onClick={() => setOpen(!open)} style={{ marginTop: 6, background: 'none', border: 'none', padding: 0, cursor: 'pointer', fontFamily: SANS, fontWeight: 700, fontSize: 13.5, color: T.teal }}>
          {open ? 'Show less' : 'Read more'}
        </button>
      )}
    </div>
  );
}

/* ── official response (learning-loop acknowledgement) ── */
function OfficialResponse({ r }) {
  return (
    <div style={{ marginTop: 12, marginLeft: 6, background: T.navy, borderRadius: 14, padding: '13px 15px' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 7 }}>
        <div style={{ width: 26, height: 26, borderRadius: 999, background: 'rgba(207,154,53,0.16)', border: `1px solid ${T.gold}66`, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <Icon name="sparkle" size={14} color={T.gold} />
        </div>
        <span style={{ fontFamily: SANS, fontWeight: 800, fontSize: 13.5, color: '#fff' }}>GoWithMe</span>
        <span style={{ fontFamily: SANS, fontSize: 11, fontWeight: 700, color: T.navy, background: T.gold, padding: '2px 7px', borderRadius: 6 }}>OFFICIAL</span>
        <span style={{ fontFamily: SANS, fontSize: 11.5, color: 'rgba(255,255,255,0.5)', marginLeft: 'auto' }}>{r.date}</span>
      </div>
      <p style={{ fontFamily: SANS, fontSize: 13.5, lineHeight: 1.55, color: 'rgba(255,255,255,0.82)', margin: 0, textWrap: 'pretty' }}>{r.text}</p>
    </div>
  );
}

/* ── one contribution card ── */
function ContributionCard({ item, aiLearning = true }) {
  const [voted, setVoted] = React.useState(false);
  const [count, setCount] = React.useState(item.helpful || 0);
  const a = item.author;
  const toggleHelpful = () => { setVoted((v) => { setCount((c) => c + (v ? -1 : 1)); return !v; }); };

  return (
    <div style={{ background: T.card, border: `1px solid ${T.line}`, borderRadius: 18, padding: 16, boxShadow: '0 4px 16px rgba(16,40,66,0.05)' }}>
      {/* author */}
      <div style={{ display: 'flex', gap: 12, alignItems: 'flex-start' }}>
        <AuthorAvatar author={a} size={44} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 7, flexWrap: 'wrap' }}>
            <span style={{ fontFamily: SANS, fontWeight: 800, fontSize: 15, color: T.ink }}>{a.name}</span>
            <span style={{ fontSize: 14 }}>{a.flag}</span>
            {item.mine && <span style={{ fontFamily: SANS, fontWeight: 800, fontSize: 10.5, color: T.teal, background: T.tealBg, padding: '2px 7px', borderRadius: 6 }}>YOU</span>}
          </div>
          <div style={{ fontFamily: SANS, fontSize: 12.5, color: T.muted, marginTop: 1 }}>
            {a.sub}{a.sub ? ' · ' : ''}{item.date}
          </div>
        </div>
        <TypePill type={item.type} small />
      </div>

      {/* badges */}
      {a.badges && a.badges.length > 0 && (
        <div style={{ display: 'flex', gap: 7, flexWrap: 'wrap', marginTop: 11 }}>
          {a.badges.map((b) => <TrustBadge key={b} kind={b} />)}
        </div>
      )}

      {/* review stars + sub */}
      {item.type === 'review' && item.rating != null && (
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 12 }}>
          <StarRow value={item.rating} size={17} />
          <span style={{ fontFamily: SANS, fontWeight: 800, fontSize: 14, color: T.ink }}>{item.rating.toFixed(1)}</span>
        </div>
      )}

      {/* correction field callout */}
      {item.type === 'correction' && item.field && (
        <div style={{ display: 'inline-flex', alignItems: 'center', gap: 7, marginTop: 12, padding: '7px 12px', borderRadius: 9, background: T.warnBg, color: T.goldDk, fontFamily: SANS, fontWeight: 700, fontSize: 12.5 }}>
          <Icon name="flag" size={13} color={T.goldDk} />Suggests updating: {item.field}
        </div>
      )}

      {/* title (stories) */}
      {item.title && (
        <h3 style={{ fontFamily: DISP, fontWeight: 700, fontSize: 19, color: T.ink, margin: '13px 0 8px', lineHeight: 1.2 }}>{item.title}</h3>
      )}

      {/* body */}
      <div style={{ marginTop: item.title ? 0 : 12 }}><ClampText text={item.text} /></div>

      {/* tip tags */}
      {item.tags && item.tags.length > 0 && (
        <div style={{ display: 'flex', gap: 7, flexWrap: 'wrap', marginTop: 12 }}>
          {item.tags.map((t) => (
            <span key={t} style={{ display: 'inline-flex', alignItems: 'center', gap: 5, padding: '5px 10px', borderRadius: 8, background: T.tealBg, color: T.tealDk, fontFamily: SANS, fontWeight: 700, fontSize: 12 }}>
              <Icon name="info" size={12} color={T.tealDk} />{t}
            </span>
          ))}
        </div>
      )}

      {/* photos */}
      {item.photos && item.photos.length > 0 && (
        <div style={{ display: 'flex', gap: 8, marginTop: 13, overflowX: 'auto', margin: '13px -2px 0', padding: '0 2px' }}>
          {item.photos.map((p, i) => <Photo key={i} p={p} size={item.type === 'photo' ? 108 : 84} radius={12} />)}
        </div>
      )}

      {/* AI learning status */}
      {aiLearning && item.aiStatus && (
        <div style={{ marginTop: 13 }}><AIChip status={item.aiStatus} /></div>
      )}

      {/* official response */}
      {item.response && <OfficialResponse r={item.response} />}

      {/* footer actions */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 14, paddingTop: 13, borderTop: `1px solid ${T.line}` }}>
        <button onClick={toggleHelpful} style={{
          display: 'flex', alignItems: 'center', gap: 7, padding: '8px 13px', borderRadius: 10, cursor: 'pointer',
          border: `1px solid ${voted ? T.teal : T.line}`, background: voted ? T.tealBg : T.white,
          fontFamily: SANS, fontWeight: 700, fontSize: 13, color: voted ? T.tealDk : T.body, transition: 'all .15s',
        }}>
          <Icon name="thumbs-up" size={15} color={voted ? T.teal : T.muted} fill={voted ? T.teal : 'none'} />
          Helpful · {fmtK(count)}
        </button>
        <button style={ghostAction}><Icon name="reply" size={15} color={T.muted} />Reply</button>
        <button style={{ ...ghostAction, marginLeft: 'auto', padding: '8px 10px' }}><Icon name="flag" size={15} color={T.muted} /></button>
      </div>
    </div>
  );
}
const ghostAction = { display: 'flex', alignItems: 'center', gap: 6, padding: '8px 12px', borderRadius: 10, cursor: 'pointer', border: `1px solid ${T.line}`, background: T.white, fontFamily: SANS, fontWeight: 700, fontSize: 13, color: T.body };

/* ── "share your experience" prompt with type chips ── */
function SharePrompt({ onWrite, dense }) {
  return (
    <div style={{ background: T.navy, borderRadius: 18, padding: dense ? 15 : 17 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
        <AuthorAvatar author={HM.ME} size={40} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontFamily: SANS, fontWeight: 800, fontSize: 15, color: '#fff' }}>Share your experience</div>
          <div style={{ fontFamily: SANS, fontSize: 12.5, color: 'rgba(255,255,255,0.6)' }}>Your input trains this place's AI guide</div>
        </div>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, marginTop: 13 }}>
        {HM.CTYPE_ORDER.map((tp) => {
          const c = HM.CTYPES[tp];
          return (
            <button key={tp} onClick={() => onWrite(tp)} className="gw-press" style={{
              display: 'flex', alignItems: 'center', gap: 8, padding: '11px 12px', borderRadius: 12, cursor: 'pointer',
              background: 'rgba(255,255,255,0.07)', border: '1px solid rgba(255,255,255,0.13)', textAlign: 'left',
            }}>
              <span style={{ width: 28, height: 28, borderRadius: 8, background: c.bg, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                <Icon name={c.icon} size={15} color={c.color} />
              </span>
              <span style={{ fontFamily: SANS, fontWeight: 700, fontSize: 13, color: '#fff', whiteSpace: 'nowrap' }}>{c.label}</span>
            </button>
          );
        })}
        <button onClick={() => onWrite(null)} className="gw-press" style={{
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, padding: '11px 12px', borderRadius: 12, cursor: 'pointer',
          background: T.gold, border: 'none',
        }}>
          <Icon name="edit" size={15} color="#fff" />
          <span style={{ fontFamily: SANS, fontWeight: 800, fontSize: 13, color: '#fff', whiteSpace: 'nowrap' }}>Write</span>
        </button>
      </div>
    </div>
  );
}

/* ── Place Detail section (condensed) ── */
function CommunitySection({ data, onOpenAll, onWrite, aiLearning = true }) {
  const top = data.items.slice(0, 2);
  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', margin: '0 0 14px' }}>
        <h2 style={{ fontFamily: DISP, fontWeight: 700, fontSize: 22, color: T.ink, margin: 0 }}>Reviews &amp; Stories</h2>
        <button onClick={onOpenAll} style={{ background: 'none', border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 5, fontFamily: SANS, fontWeight: 700, fontSize: 14.5, color: T.teal }}>
          See all <Icon name="arrow-right" size={15} color={T.teal} />
        </button>
      </div>

      <div style={{ background: T.white, border: `1px solid ${T.line}`, borderRadius: 18, padding: 16 }}>
        <RatingSummary data={data} />
      </div>

      {aiLearning && (
        <div style={{ display: 'flex', gap: 10, alignItems: 'center', marginTop: 12, background: T.tealBg, border: `1px solid ${T.teal}2e`, borderRadius: 14, padding: '12px 14px' }}>
          <Icon name="sparkle" size={18} color={T.teal} />
          <span style={{ fontFamily: SANS, fontSize: 13, lineHeight: 1.45, color: T.tealDk, fontWeight: 600 }}>
            Traveler reviews &amp; stories continuously improve this place's AI guide.
          </span>
        </div>
      )}

      <div style={{ marginTop: 14 }}><SharePrompt onWrite={onWrite} /></div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 13, marginTop: 14 }}>
        {top.map((it) => <ContributionCard key={it.id} item={it} aiLearning={aiLearning} />)}
      </div>

      <button onClick={onOpenAll} className="gw-press" style={{
        width: '100%', marginTop: 13, padding: 15, borderRadius: 14, cursor: 'pointer',
        background: T.white, border: `1px solid ${T.line}`, fontFamily: SANS, fontWeight: 700, fontSize: 15, color: T.ink,
        display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
      }}>
        <Icon name="users" size={18} color={T.navy} />
        Read all {fmtK(data.total)} contributions
      </button>
    </div>
  );
}

Object.assign(window, {
  fmtK, StarRow, StarInput, AuthorAvatar, TrustBadge, TypePill, AIChip,
  SubRatings, DistBars, RatingSummary, Photo, ClampText, OfficialResponse,
  ContributionCard, SharePrompt, CommunitySection,
});
