function SaveImageSheet({ post, onClose, onDone }) {
  const { BottomSheet, Button } = window.SpotureDesignSystem_f7ad96;
  const params = new URLSearchParams(location.search);
  const p = post || {};
  const count = p.mediaCount || 1;
  const srcs = p.srcs || (p.src ? [p.src] : []);
  const media = Array.from({ length: count }, (_, i) => ({ i, src: srcs[i] || (i === 0 ? p.src : null), video: p.hasVideo && i === count - 1 }));
  const [phase, setPhase] = React.useState(params.get('save') === 'perm' ? 'perm' : params.get('save') === 'saving' ? 'saving' : params.get('save') === 'done' ? 'done' : 'pick');
  const [sel, setSel] = React.useState(Array.from({ length: count }, (_, i) => i));
  const [mark, setMark] = React.useState(true);
  const [granted, setGranted] = React.useState(false);
  const toggle = (i) => setSel(s => s.includes(i) ? s.filter(x => x !== i) : s.concat(i).sort((a, b) => a - b));
  const all = sel.length === count;
  const n = sel.length;
  React.useEffect(() => {
    if (phase !== 'saving') return;
    const t = setTimeout(() => setPhase('done'), 1400);
    return () => clearTimeout(t);
  }, [phase]);
  const start = () => setPhase(granted ? 'saving' : 'perm');

  if (phase === 'perm') return (
    <div style={{ position: 'fixed', inset: 0, background: 'rgba(20,20,20,.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 26, zIndex: 96 }}>
      <div style={{ width: '100%', background: 'var(--surface-1)', borderRadius: 22, padding: '26px 22px 22px', boxShadow: 'var(--shadow-float)', boxSizing: 'border-box' }}>
        <div style={{ width: 54, height: 54, borderRadius: '50%', background: 'var(--surface-2)', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 15px' }}><i className="ti ti-photo-plus" style={{ fontSize: 24, color: 'var(--text-secondary)' }}></i></div>
        <span style={{ font: 'var(--text-heading)', display: 'block', textAlign: 'center', marginBottom: 8 }}>사진 저장 권한이 필요해요</span>
        <p style={{ font: 'var(--text-caption)', color: 'var(--text-secondary)', textAlign: 'center', margin: '0 0 18px', lineHeight: 1.6, textWrap: 'pretty' }}>내려받은 사진을 기기 앨범에 넣기 위해서만 써요. 앨범을 읽지는 않아요.</p>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 9 }}>
          <span onClick={() => { setGranted(true); setPhase('saving'); }} style={{ textAlign: 'center', font: '600 15px/1 var(--font-family)', color: '#fff', background: 'var(--bg-ink)', borderRadius: 999, padding: '17px 0', cursor: 'pointer' }}>허용하고 저장</span>
          <span onClick={() => setPhase('pick')} style={{ textAlign: 'center', font: '600 15px/1 var(--font-family)', color: 'var(--text-secondary)', borderRadius: 999, padding: '15px 0', cursor: 'pointer' }}>지금은 안 할게요</span>
        </div>
      </div>
    </div>
  );

  if (phase === 'saving' || phase === 'done') {
    const done = phase === 'done';
    return (
      <div style={{ position: 'fixed', inset: 0, background: 'rgba(20,20,20,.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 26, zIndex: 96 }}>
        <div style={{ width: '100%', background: 'var(--surface-1)', borderRadius: 22, padding: '26px 22px 22px', boxShadow: 'var(--shadow-float)', boxSizing: 'border-box' }}>
          <div style={{ width: 54, height: 54, borderRadius: '50%', background: done ? 'var(--bg-success)' : 'var(--surface-2)', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 15px' }}><i className={done ? 'ti ti-check' : 'ti ti-loader-2'} style={{ fontSize: 25, color: done ? 'var(--text-success)' : 'var(--text-secondary)' }}></i></div>
          <span style={{ font: 'var(--text-heading)', display: 'block', textAlign: 'center', marginBottom: 8 }}>{done ? '앨범에 저장했어요' : '저장하고 있어요'}</span>
          <p style={{ font: 'var(--text-caption)', color: 'var(--text-secondary)', textAlign: 'center', margin: '0 0 18px', lineHeight: 1.6 }}>{done ? '사진 ' + n + '장 · Spoture 앨범' : '사진 ' + n + '장을 내려받는 중'}</p>
          {!done && <div style={{ height: 4, borderRadius: 999, background: 'var(--border)', overflow: 'hidden', marginBottom: 20 }}><div style={{ width: '62%', height: '100%', borderRadius: 999, background: 'var(--text-accent)' }}></div></div>}
          {done && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10, background: 'var(--surface-2)', borderRadius: 'var(--radius-tile)', padding: '15px 16px', marginBottom: 20 }}>
              <div style={{ display: 'flex', gap: 10 }}>
                <i className={mark ? 'ti ti-copyright' : 'ti ti-photo'} style={{ fontSize: 15, color: 'var(--text-secondary)', flexShrink: 0, marginTop: 2 }}></i>
                <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)', lineHeight: 1.55 }}>{mark ? '가게 이름과 Spoture 마크가 사진 아래에 들어갔어요' : '워터마크 없이 원본으로 저장했어요'}</span>
              </div>
              <div style={{ display: 'flex', gap: 10 }}>
                <i className="ti ti-map-pin-off" style={{ fontSize: 15, color: 'var(--text-secondary)', flexShrink: 0, marginTop: 2 }}></i>
                <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)', lineHeight: 1.55 }}>위치 정보(EXIF)는 지워서 저장했어요</span>
              </div>
            </div>
          )}
          {done && <span onClick={() => { onDone && onDone(n); onClose && onClose(); }} style={{ display: 'block', textAlign: 'center', font: '600 15px/1 var(--font-family)', color: '#fff', background: 'var(--bg-ink)', borderRadius: 999, padding: '17px 0', cursor: 'pointer' }}>확인</span>}
        </div>
      </div>
    );
  }

  return (
    <BottomSheet title="이미지 저장" titleAside={<span onClick={() => setSel(all ? [] : media.map(m => m.i))} style={{ font: '600 13px/1 var(--font-family)', color: 'var(--text-primary)', cursor: 'pointer' }}>{all ? '전체 해제' : '전체 선택'}</span>} onClose={onClose}
      footer={<div><Button variant="primary" disabled={!n} onClick={start}>{n ? '사진 ' + n + '장 저장' : '저장할 사진을 골라주세요'}</Button></div>}>
      <p style={{ font: 'var(--text-caption)', color: 'var(--text-secondary)', margin: '0 0 14px', lineHeight: 1.6 }}>저장할 사진을 골라주세요. 기기 앨범에 원본 화질로 들어가요.</p>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 8, marginBottom: 18 }}>
        {media.map(m => {
          const on = sel.includes(m.i);
          return (
            <div key={m.i} onClick={() => toggle(m.i)} style={{ position: 'relative', aspectRatio: '1', borderRadius: 12, overflow: 'hidden', background: 'var(--surface-2)', cursor: 'pointer', boxShadow: on ? 'inset 0 0 0 2px var(--text-accent)' : 'inset 0 0 0 1px var(--border)' }}>
              {m.src
                ? <img src={m.src} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block', opacity: on ? 1 : .5 }} />
                : <div style={{ width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', opacity: on ? 1 : .5 }}><i className={m.video ? 'ti ti-video' : 'ti ti-photo'} style={{ fontSize: 21, color: 'var(--text-muted)' }}></i></div>}
              <span style={{ position: 'absolute', right: 5, top: 5, width: 22, height: 22, borderRadius: '50%', background: on ? 'var(--text-accent)' : 'rgba(26,26,26,.42)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><i className={on ? 'ti ti-check' : 'ti ti-plus'} style={{ fontSize: 12, color: '#fff' }}></i></span>
              {m.video && <span style={{ position: 'absolute', left: 6, bottom: 6, font: '600 10px/1 var(--font-family)', color: '#fff', background: 'rgba(26,26,26,.66)', borderRadius: 999, padding: '4px 7px' }}>동영상</span>}
            </div>
          );
        })}
      </div>
      <div onClick={() => setMark(v => !v)} style={{ display: 'flex', alignItems: 'center', gap: 12, background: 'var(--surface-2)', borderRadius: 'var(--radius-tile)', padding: '14px 16px', cursor: 'pointer', marginBottom: 10 }}>
        <i className="ti ti-copyright" style={{ fontSize: 18, color: 'var(--text-secondary)', flexShrink: 0 }}></i>
        <div style={{ flex: 1, minWidth: 0 }}>
          <span style={{ font: 'var(--text-body)', display: 'block', marginBottom: 2 }}>가게 이름 · 워터마크 넣기</span>
          <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)' }}>{p.place ? p.place + ' · Spoture' : 'Spoture'} 표기가 사진 아래에 들어가요</span>
        </div>
        <span style={{ width: 44, height: 26, borderRadius: 999, background: mark ? 'var(--text-accent)' : 'var(--border-strong)', padding: 3, boxSizing: 'border-box', flexShrink: 0, display: 'flex', justifyContent: mark ? 'flex-end' : 'flex-start', transition: 'all .16s ease' }}><span style={{ width: 20, height: 20, borderRadius: '50%', background: '#fff' }}></span></span>
      </div>
      <div style={{ display: 'flex', gap: 10, background: 'var(--surface-2)', borderRadius: 'var(--radius-tile)', padding: '13px 14px' }}>
        <i className="ti ti-shield-lock" style={{ fontSize: 15, color: 'var(--text-secondary)', flexShrink: 0, marginTop: 1 }}></i>
        <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)', lineHeight: 1.6 }}>{p.isMine || p.user === '국밥러버92' ? '내 사진이라 자유롭게 쓸 수 있어요. 위치 정보는 지워서 저장돼요.' : '이웃이 올린 사진이에요. 상업적 용도로 쓰거나 출처 없이 올리지 말아주세요.'}</span>
      </div>
    </BottomSheet>
  );
}
window.SaveImageSheet = SaveImageSheet;
