function PinPickerSheet({ title = '지도에서 직접 핀 찍기', cta = '이 위치로 등록하기', initialQ, onClose, onDone }) {
  const { Button } = window.SpotureDesignSystem_f7ad96;
  const params = new URLSearchParams(location.search);
  const [q, setQ] = React.useState(initialQ != null ? initialQ : (params.get('pinq') || ''));
  const [name, setName] = React.useState('');
  const [detail, setDetail] = React.useState('');
  const [cat, setCat] = React.useState(null);

  const [moved, setMoved] = React.useState(null);
  const [off, setOff] = React.useState({ x: 0, y: 0 });
  const [pickedAddr, setPickedAddr] = React.useState(null);
  const [dragging, setDragging] = React.useState(false);
  const drag = React.useRef(null);
  const josa = (w) => { const c = (w || '').charCodeAt((w || '').length - 1) - 44032; return (c >= 0 && c < 11172 && c % 28 !== 0) ? '으로' : '로'; };
  const roads = ['테헤란로', '역삼로', '언주로', '논현로'];
  const awayRoads = ['중앙로', '시장로', '역전로', '큰길로'];
  const region = q.trim();
  const addr = pickedAddr || ((region ? region + ' ' : '서울 강남구 ') + (region ? awayRoads : roads)[Math.abs(Math.round(off.x / 90)) % 4] + ' ' + (11 + Math.abs(Math.round(off.y / 12)) * 2));
  const onMapDown = (ev) => { setPickedAddr(null); drag.current = { px: ev.clientX, py: ev.clientY, ox: off.x, oy: off.y }; setDragging(true); ev.currentTarget.setPointerCapture && ev.currentTarget.setPointerCapture(ev.pointerId); };
  const onMapMove = (ev) => { const d = drag.current; if (!d) return; setOff({ x: d.ox + (ev.clientX - d.px), y: d.oy + (ev.clientY - d.py) }); };
  const onMapUp = () => { drag.current = null; setDragging(false); };
  const valid = name.trim().length > 0 && !!cat;
  return (
    <div style={{ position: 'absolute', inset: 0, background: 'rgba(20,20,20,.42)', display: 'flex', alignItems: 'flex-end', zIndex: 75 }}>
      <div style={{ width: '100%', height: '96%', background: 'var(--surface-1)', borderRadius: 'var(--radius-sheet) var(--radius-sheet) 0 0', boxShadow: 'var(--shadow-sheet)', display: 'flex', flexDirection: 'column', minHeight: 0, overflow: 'hidden' }}>
        <div style={{ flexShrink: 0, padding: '14px 20px 0' }}>
          <div style={{ width: 40, height: 4, borderRadius: 2, background: 'var(--border-strong)', margin: '0 auto 16px' }}></div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12, paddingBottom: 14, borderBottom: '1px solid var(--border)' }}>
            <span style={{ flex: 1, minWidth: 0, font: 'var(--text-heading)' }}>{title}</span>
            <i className="ti ti-x" onClick={onClose} style={{ fontSize: 19, color: 'var(--text-muted)', cursor: 'pointer', flexShrink: 0 }}></i>
          </div>
        </div>
        <div onPointerDown={onMapDown} onPointerMove={onMapMove} onPointerUp={onMapUp} onPointerCancel={onMapUp}
          style={{ flexShrink: 0, height: 220, background: 'var(--surface-2)', position: 'relative', overflow: 'hidden', margin: '14px 20px 0', borderRadius: 'var(--radius-card)', cursor: dragging ? 'grabbing' : 'grab', touchAction: 'none' }}>
          <div style={{ position: 'absolute', inset: '-50%', backgroundImage: 'linear-gradient(var(--border) 1px, transparent 1px), linear-gradient(90deg, var(--border) 1px, transparent 1px)', backgroundSize: '38px 38px', transform: 'translate(' + (off.x % 38) + 'px,' + (off.y % 38) + 'px)' }}></div>
          <div style={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%,-100%)', pointerEvents: 'none', zIndex: 2 }}>
            <span style={{ width: 38, height: 38, background: 'var(--text-accent)', borderRadius: '50% 50% 50% 0', transform: 'rotate(-45deg)', display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: 'var(--shadow-float)', marginBottom: dragging ? 16 : 6, transition: 'margin .16s ease' }}><i className="ti ti-tools-kitchen-2" style={{ fontSize: 17, color: '#fff', transform: 'rotate(45deg)' }}></i></span>
          </div>
          <span style={{ position: 'absolute', left: '50%', top: '50%', width: 14, height: 14, borderRadius: '50%', background: 'rgba(227,30,36,.18)', border: '1.5px solid rgba(227,30,36,.45)', boxSizing: 'border-box', transform: 'translate(-50%,-50%)', pointerEvents: 'none', zIndex: 1 }}></span>
          <span style={{ position: 'absolute', left: 16, top: 14, maxWidth: 'calc(100% - 32px)', display: 'inline-flex', alignItems: 'center', gap: 5, font: 'var(--text-micro)', color: '#fff', background: 'rgba(26,26,26,.7)', borderRadius: 999, padding: '8px 12px', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', pointerEvents: 'none' }}>
            <i className={moved ? 'ti ti-map-search' : 'ti ti-drag-drop'} style={{ fontSize: 12, flexShrink: 0 }}></i>{moved ? moved + josa(moved) + ' 이동했어요 · 핀을 맞춰주세요' : '지도를 움직여 위치를 맞춰주세요'}
          </span>
        </div>
        <div style={{ flexShrink: 0, padding: '14px 20px 0' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, background: 'var(--surface-2)', borderRadius: 'var(--radius-chip)', padding: '13px 16px', boxSizing: 'border-box' }}>
            <i className="ti ti-search" style={{ fontSize: 16, color: 'var(--text-muted)', flexShrink: 0 }}></i>
            <input value={q} onChange={e => { setQ(e.target.value); setMoved(e.target.value.trim() || null); setPickedAddr(null); }} placeholder="지역 · 건물 · 지하철역으로 이동" style={{ flex: 1, minWidth: 0, border: 'none', outline: 'none', background: 'transparent', font: 'var(--text-body)', color: 'var(--text-primary)', fontFamily: 'var(--font-family)' }} />
            {q && <i className="ti ti-x" onClick={() => { setQ(''); setMoved(null); }} style={{ fontSize: 15, color: 'var(--text-muted)', cursor: 'pointer', flexShrink: 0 }}></i>}
          </div>
        </div>
        <div style={{ flex: '1 1 0%', minHeight: 0, overflowY: 'auto', padding: '14px 20px 8px' }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            <div style={{ display: 'flex', gap: 10, background: 'var(--surface-2)', borderRadius: 'var(--radius-tile)', padding: '13px 14px' }}>
              <i className="ti ti-map-pin-check" style={{ fontSize: 16, color: 'var(--text-success)', flexShrink: 0, marginTop: 1 }}></i>
              <div style={{ minWidth: 0 }}>
                <span style={{ font: 'var(--text-small)', color: 'var(--text-muted)', display: 'block', marginBottom: 3 }}>핀이 놓인 자리의 도로명 주소</span>
                <span style={{ font: 'var(--text-body-strong)' }}>{addr}</span>
              </div>
            </div>
            <div>
              <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)', display: 'block', marginBottom: 6 }}>상호명 <span style={{ color: 'var(--text-accent)' }}>· 필수</span></span>
              <input value={name} onChange={e => setName(e.target.value.slice(0, 30))} placeholder="예: 할매순대국 강남점" style={{ width: '100%', boxSizing: 'border-box', background: 'var(--surface-1)', border: '1px solid ' + (name.trim() ? 'var(--border-accent)' : 'var(--border)'), borderRadius: 'var(--radius-chip)', padding: '14px 16px', outline: 'none', font: 'var(--text-body)', color: 'var(--text-primary)', fontFamily: 'var(--font-family)' }} />
            </div>
            <div>
              <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)', display: 'block', marginBottom: 8 }}>업종 <span style={{ color: 'var(--text-accent)' }}>· 필수</span></span>
              <CategoryPicker value={cat} onChange={setCat} />
            </div>
            <div>
              <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)', display: 'block', marginBottom: 6 }}>상세 주소 <span style={{ color: 'var(--text-muted)' }}>· 선택</span></span>
              <input value={detail} onChange={e => setDetail(e.target.value.slice(0, 40))} placeholder="예: 2층 · 지하상가 B동 14호" style={{ width: '100%', boxSizing: 'border-box', background: 'var(--surface-1)', border: '1px solid var(--border)', borderRadius: 'var(--radius-chip)', padding: '14px 16px', outline: 'none', font: 'var(--text-body)', color: 'var(--text-primary)', fontFamily: 'var(--font-family)' }} />
              <p style={{ font: 'var(--text-micro)', color: 'var(--text-muted)', margin: '7px 0 0', lineHeight: 1.6 }}>층·호수까지 적어주면 이웃이 찾기 쉬워요. 새 가게로 등록되고 확인 후 지도에 반영돼요.</p>
            </div>
          </div>
        </div>
        <div style={{ flexShrink: 0, padding: '14px 20px 22px', borderTop: '1px solid var(--border)' }}>
          <Button variant="primary" disabled={!valid} onClick={() => valid && onDone && onDone(name.trim(), { addr, detail: detail.trim(), category: cat })}>{valid ? cta : (name.trim() ? '업종을 골라주세요' : '상호명을 입력해주세요')}</Button>
        </div>
      </div>
    </div>
  );
}
window.PinPickerSheet = PinPickerSheet;
