const VIS_ORDER = ['public', 'followers', 'private'];
const VIS_META = {
  public: { key: 'public', label: '전체 공개', icon: 'world', sub: '누구나 보고 지도에서 찾을 수 있어요', note: '미션 · 핫플레이스 집계에 포함돼요', tone: 'var(--text-accent)', bg: 'var(--bg-accent)' },
  followers: { key: 'followers', label: '팔로워 공개', icon: 'users', sub: '나를 팔로우하는 이웃만 볼 수 있어요', note: '장소 제안도 팔로우 이웃만 보낼 수 있어요', tone: '#3B6FD9', bg: 'rgba(59,111,217,.10)' },
  private: { key: 'private', label: '비공개', icon: 'lock', sub: '나만 볼 수 있어요', note: '배지 · 챌린지 집계에는 그대로 반영돼요', tone: 'var(--text-secondary)', bg: 'var(--surface-2)' }
};
const visMeta = (k) => VIS_META[k] || VIS_META.public;
const visRank = (k) => Math.max(0, VIS_ORDER.indexOf(k));
const effVis = (account, item) => VIS_ORDER[Math.max(visRank(account), visRank(item))];
const visCapped = (account, item) => effVis(account, item) !== item;
function accountVis() {
  if (!window.__accountVis) {
    const p = new URLSearchParams(location.search).get('avis');
    window.__accountVis = VIS_ORDER.indexOf(p) > -1 ? p : 'public';
  }
  return window.__accountVis;
}
function setAccountVis(v) { window.__accountVis = v; }
const postKey = (p) => (p && (p._key || p.imageId || p.menu || p.place)) || 'post';
window.__postVis = window.__postVis || {};
const postVisGet = (p) => window.__postVis[postKey(p)] || (p && p.vis) || null;
const postVisSet = (p, val) => { window.__postVis[postKey(p)] = val; };
Object.assign(window, { postVisGet, postVisSet });
Object.assign(window, { VIS_ORDER, VIS_META, visMeta, visRank, effVis, visCapped, accountVis, setAccountVis });

function VisibilityChip({ v, size }) {
  const m = visMeta(v), sm = size === 'sm';
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, flexShrink: 0, background: m.bg, color: m.tone, borderRadius: 999, padding: sm ? '4px 8px' : '6px 10px', font: '600 ' + (sm ? 11 : 12) + 'px/1 var(--font-family)' }}>
      <i className={'ti ti-' + m.icon} style={{ fontSize: sm ? 12 : 13 }}></i>{m.label}
    </span>
  );
}
window.VisibilityChip = VisibilityChip;

function VisibilityOptions({ value, onChange, account, scopeWord }) {
  const acc = account || 'public';
  const word = scopeWord || '게시물';
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
      {VIS_ORDER.map(k => {
        const m = VIS_META[k], on = value === k, capped = visRank(acc) > visRank(k);
        return (
          <div key={k} onClick={() => onChange(k)} style={{ display: 'flex', alignItems: 'flex-start', gap: 12, padding: '15px 16px', background: on ? m.bg : 'var(--surface-2)', border: '1.5px solid ' + (on ? m.tone : 'transparent'), borderRadius: 'var(--radius-tile)', cursor: 'pointer' }}>
            <i className={'ti ti-' + m.icon} style={{ fontSize: 19, color: on ? m.tone : 'var(--text-secondary)', flexShrink: 0, marginTop: 1 }}></i>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 }}>
                <span style={{ font: 'var(--text-body-strong)', color: on ? m.tone : 'var(--text-primary)' }}>{m.label}</span>
                {capped && <span style={{ font: '600 10px/1 var(--font-family)', color: 'var(--text-warning)', background: 'var(--bg-warning)', borderRadius: 999, padding: '4px 6px' }}>지금은 적용 안 됨</span>}
              </div>
              <div style={{ font: 'var(--text-small)', color: 'var(--text-secondary)', lineHeight: 1.5, marginBottom: on ? 6 : 0 }}>{m.sub}</div>
              {on && <div style={{ font: 'var(--text-micro)', color: 'var(--text-muted)' }}>{capped ? '설정의 계정 공개 범위(' + visMeta(acc).label + ')가 더 좁아서 이 ' + word + '은 ' + visMeta(effVis(acc, k)).label + '로 보여요' : m.note}</div>}
            </div>
            <span style={{ width: 18, height: 18, borderRadius: '50%', border: '2px solid ' + (on ? m.tone : 'var(--border-strong)'), background: on ? m.tone : 'transparent', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, marginTop: 2 }}>{on && <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#fff' }}></span>}</span>
          </div>
        );
      })}
    </div>
  );
}
window.VisibilityOptions = VisibilityOptions;

function VisibilityNotice({ account, item, word, onOpenSettings }) {
  const acc = account || 'public';
  if (!visCapped(acc, item)) return null;
  const eff = effVis(acc, item), w = word || '게시물';
  return (
    <div style={{ display: 'flex', gap: 10, background: 'var(--bg-warning)', border: '1px solid var(--border)', borderRadius: 'var(--radius-tile)', padding: '13px 14px' }}>
      <i className="ti ti-alert-triangle" style={{ fontSize: 16, color: 'var(--text-warning)', flexShrink: 0, marginTop: 1 }}></i>
      <div style={{ flex: 1, minWidth: 0 }}>
        <span style={{ font: 'var(--text-small)', color: 'var(--text-primary)', lineHeight: 1.6, display: 'block' }}>
          이 {w}은 <b>{visMeta(item).label}</b>로 설정했지만, 계정 공개 범위가 <b>{visMeta(acc).label}</b>라서 지금은 <b style={{ color: visMeta(eff).tone }}>{visMeta(eff).label}</b> 상태예요.
        </span>
        {onOpenSettings && <span onClick={onOpenSettings} style={{ display: 'inline-block', marginTop: 8, font: '600 12px/1 var(--font-family)', color: 'var(--text-accent)', cursor: 'pointer' }}>설정에서 계정 공개 범위 바꾸기 →</span>}
      </div>
    </div>
  );
}
window.VisibilityNotice = VisibilityNotice;

function VisibilityRow({ value, account, onClick, word }) {
  const acc = account || 'public', eff = effVis(acc, value), m = visMeta(value), capped = visCapped(acc, value);
  return (
    <div onClick={onClick} style={{ display: 'flex', alignItems: 'center', gap: 12, background: 'var(--surface-1)', border: '1px solid ' + (capped ? 'var(--border-strong)' : 'var(--border)'), borderRadius: 'var(--radius-tile)', padding: '14px 15px', cursor: 'pointer' }}>
      <i className={'ti ti-' + m.icon} style={{ fontSize: 18, color: m.tone, flexShrink: 0 }}></i>
      <div style={{ flex: 1, minWidth: 0 }}>
        <span style={{ font: 'var(--text-body)', color: 'var(--text-primary)', display: 'block', marginBottom: 2 }}>{m.label}</span>
        <span style={{ font: 'var(--text-micro)', color: capped ? 'var(--text-warning)' : 'var(--text-muted)' }}>{capped ? '계정 설정 때문에 지금은 ' + visMeta(eff).label : (word || '게시물') + ' 공개 범위'}</span>
      </div>
      <i className="ti ti-chevron-down" style={{ fontSize: 16, color: 'var(--text-muted)', flexShrink: 0 }}></i>
    </div>
  );
}
window.VisibilityRow = VisibilityRow;

function VisibilitySheet({ current, account, onPick, onClose, word, title }) {
  const { BottomSheet, Button } = window.SpotureDesignSystem_f7ad96;
  const [sel, setSel] = React.useState(current || 'public');
  const acc = account || 'public';
  return (
    <BottomSheet title={title || ((word || '게시물') + ' 공개 범위')} footer={<Button variant="primary" onClick={() => onPick(sel)}>이 범위로 설정</Button>} onClose={onClose}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
        {acc !== 'public' && (
          <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 }}>계정 공개 범위가 <b style={{ color: 'var(--text-primary)' }}>{visMeta(acc).label}</b>예요. 여기서 더 넓게 골라도 실제 노출은 계정 설정까지만 넓어져요.</span>
          </div>
        )}
        <VisibilityOptions value={sel} onChange={setSel} account={acc} scopeWord={word} />
        <VisibilityNotice account={acc} item={sel} word={word} />
      </div>
    </BottomSheet>
  );
}
window.VisibilitySheet = VisibilitySheet;

function AccountVisibilitySheet({ current, onPick, onClose }) {
  const { BottomSheet, Button } = window.SpotureDesignSystem_f7ad96;
  const [sel, setSel] = React.useState(current || 'public');
  const effect = {
    public: ['게시물·컬렉션 각각의 공개 범위를 그대로 따라요', '전체 공개로 둔 기록은 지도와 검색에 나와요'],
    followers: ['전체 공개로 둔 게시물·컬렉션은 팔로워 공개로 좁혀져요', '팔로워 공개는 그대로, 비공개는 계속 비공개예요'],
    private: ['모든 게시물과 컬렉션이 비공개가 돼요', '개별 설정은 지워지지 않고, 범위를 다시 넓히면 되살아나요']
  };
  return (
    <BottomSheet title="계정 공개 범위" footer={<Button variant="primary" onClick={() => onPick(sel)}>이 범위로 설정</Button>} onClose={onClose}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
        <span style={{ font: 'var(--text-caption)', color: 'var(--text-secondary)', lineHeight: 1.6 }}>계정 전체에 적용되는 상한선이에요. 개별 게시물·컬렉션 설정보다 좁으면 좁은 쪽이 이겨요.</span>
        <VisibilityOptions value={sel} onChange={setSel} account="public" scopeWord="게시물" />
        <div style={{ background: 'var(--surface-2)', borderRadius: 'var(--radius-tile)', padding: '14px 16px', display: 'flex', flexDirection: 'column', gap: 9 }}>
          <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)' }}>{visMeta(sel).label}(으)로 바꾸면</span>
          {effect[sel].map(t => (
            <div key={t} style={{ display: 'flex', gap: 8 }}>
              <i className="ti ti-point-filled" style={{ fontSize: 13, color: visMeta(sel).tone, flexShrink: 0, marginTop: 2 }}></i>
              <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)', lineHeight: 1.55 }}>{t}</span>
            </div>
          ))}
        </div>
      </div>
    </BottomSheet>
  );
}
window.AccountVisibilitySheet = AccountVisibilitySheet;
