window.legalDocs = {
  terms: {
    title: '이용약관',
    sub: '2026.09.01 시행 · 6차 개정',
    version: 'v6.0',
    updated: '최근 개정일 2026.08.01',
    changes: ['장소 제안 승인 절차를 조문으로 명확히 했어요', '미션 보상 회수 기준과 이의 신청 절차를 추가했어요'],
    summary: ['사진과 위치 기록의 저작권은 작성자에게 있어요', '이웃의 위치 제안은 작성자가 승인해야 반영돼요', '미션 인증은 심사를 거쳐 보상이 지급돼요'],
    toc: ['제1조 목적', '제2조 정의', '제3조 계정과 가입', '제4조 게시물과 권리', '제5조 위치 정보와 장소 제안', '제6조 미션·배지·보상', '제7조 금지 행위', '제8조 이용 제한', '제9조 서비스 변경과 중단', '제10조 책임의 한계'],
    body: [
      { h: '제1조 목적', p: '이 약관은 Spoture(이하 "서비스")가 제공하는 위치 기반 사진 기록·공유 서비스의 이용 조건과 절차, 회사와 회원의 권리·의무를 정합니다.' },
      { h: '제2조 정의', list: ['"회원"은 이 약관에 동의하고 계정을 만든 사람을 말합니다.', '"게시물"은 회원이 올린 사진, 영상, 메뉴명, 해시태그, 위치 정보를 말합니다.', '"장소 제안"은 위치가 비어 있는 게시물에 다른 회원이 가게를 제안하는 기능을 말합니다.', '"미션"은 회사 또는 제휴사가 제시한 조건을 인증샷으로 달성하는 활동을 말합니다.'] },
      { h: '제3조 계정과 가입', p: '회원은 카카오·네이버·Apple·Google 계정으로 가입할 수 있으며, 연동 계정에서 제공받는 정보는 프로필 사진과 이메일로 한정합니다. 하나 이상의 로그인 수단은 항상 유지되어야 합니다.' },
      { h: '제4조 게시물과 권리', p: '게시물의 저작권은 작성자에게 있습니다. 회사는 서비스 운영·홍보 목적에 한해 게시물을 노출·축소·인용할 수 있으며, 작성자가 삭제하거나 공개 범위를 좁히면 즉시 중단합니다.' },
      { h: '제5조 위치 정보와 장소 제안', p: '회원은 게시물의 위치를 직접 지정하거나 비워 둘 수 있습니다. 비어 있는 게시물에는 다른 회원이 장소를 제안할 수 있으며, 작성자가 승인한 경우에만 지도에 반영됩니다. 승인 없이 위치가 확정되는 일은 없습니다.', list: ['같은 가게로 모인 제안은 하나로 묶여 작성자에게 한 번만 안내됩니다.', '제안은 등록 후 14일 안에 승인되지 않으면 자동으로 만료됩니다.', '허위 제안으로 확인된 경우 제안 이력에서 삭제되고 제안 기능이 제한될 수 있습니다.'] },
      { h: '제6조 미션·배지·보상', p: '미션 인증샷은 조건 충족 여부를 심사하며, 부정 인증(타인 사진 도용, 조작, 중복 제출)으로 확인되면 보상 지급을 거절하고 이미 지급된 배지·응모권·포인트를 회수할 수 있습니다. 회수 사유는 알림으로 안내하며, 회원은 안내를 받은 날부터 14일 안에 이의를 신청할 수 있습니다.' },
      { h: '제7조 금지 행위', list: ['타인의 사진·리뷰를 자신의 것으로 올리는 행위', '허위 위치 제안을 반복해 지도 정보를 훼손하는 행위', '영업 목적의 대량 게시 및 자동화 도구 사용', '타인을 비방하거나 개인정보를 노출하는 게시'] },
      { h: '제8조 이용 제한', p: '금지 행위가 확인되면 회사는 게시물 노출 제한, 기능 일부 정지, 계정 이용 정지 조치를 할 수 있습니다. 조치 전 사유를 알리고, 회원은 이의를 제기할 수 있습니다.' },
      { h: '제9조 서비스 변경과 중단', p: '회사는 서비스의 내용을 변경할 수 있으며, 회원에게 불리한 변경은 시행 30일 전에 공지합니다. 천재지변이나 설비 장애로 서비스가 일시 중단될 수 있습니다.' },
      { h: '제10조 책임의 한계', p: '회원 간 거래나 방문한 가게에서 발생한 문제에 대해 회사는 책임을 지지 않습니다. 다만 회사의 고의 또는 중대한 과실로 발생한 손해는 관련 법령에 따라 배상합니다.' }
    ]
  },
  privacy: {
    title: '개인정보처리방침',
    sub: '2026.09.01 시행 · 4차 개정',
    version: 'v4.0',
    updated: '최근 개정일 2026.08.01',
    changes: ['미션 심사·보상 회수 기록의 보관 기간을 명시했어요', '위탁사 목록을 최신 상태로 갱신했어요'],
    summary: ['위치는 사진의 장소 추정에만 쓰고, 이동 경로는 저장하지 않아요', '집 주소 같은 정확한 좌표는 이웃에게 공개되지 않아요', '탈퇴하면 30일 후 모든 기록이 삭제돼요'],
    toc: ['1. 수집하는 항목', '2. 이용 목적', '3. 위치 정보 처리', '4. 보관 기간', '5. 제3자 제공', '6. 처리 위탁', '7. 이용자의 권리', '8. 안전성 확보 조치', '9. 문의처'],
    body: [
      { h: '1. 수집하는 항목', list: ['필수: 이메일, 소셜 계정 식별자, 닉네임, 기기 정보', '서비스 이용 중: 사진·영상, 메뉴명, 해시태그, 게시물 위치, 좋아요·댓글 기록', '선택: 프로필 사진, 소개, 활동 동네, 단말 위치(허용 시)'] },
      { h: '2. 이용 목적', p: '계정 식별과 로그인, 사진의 장소 추정과 지도 표시, 동네 기반 추천, 미션 심사와 보상 지급, 부정 이용 방지, 고객 문의 응대에 사용합니다. 마케팅 알림은 별도 동의를 받은 회원에게만 발송합니다.' },
      { h: '3. 위치 정보 처리', p: '단말 위치는 사진을 올리는 순간 근처 가게 후보를 찾기 위해서만 사용하고, 백그라운드에서 이동 경로를 수집하지 않습니다. 게시물에 표시되는 위치는 회원이 지정한 가게이며, 가게가 아닌 사진은 동 단위까지만 표시됩니다. 위치 권한은 설정에서 언제든 끌 수 있습니다.' },
      { h: '4. 보관 기간', list: ['회원 정보: 탈퇴 후 30일간 보관한 뒤 삭제(부정 이용 재가입 방지)', '게시물: 삭제 즉시 노출 중단, 백업에서 최대 7일 내 완전 삭제', '미션 심사·보상 회수 기록: 분쟁 대응을 위해 1년간 보관한 뒤 삭제', '전자상거래법 등 법령이 정한 기록: 법정 기간 동안 별도 보관'] },
      { h: '5. 제3자 제공', p: '원칙적으로 제3자에게 제공하지 않습니다. 제휴 미션에 참여한 경우, 보상 지급에 필요한 최소 정보(닉네임, 인증 결과)만 해당 제휴사에 전달하며 참여 시 별도로 안내합니다.' },
      { h: '6. 처리 위탁', list: ['클라우드 인프라·이미지 저장: Amazon Web Services (국내 리전)', '푸시 알림 발송: Firebase Cloud Messaging', '지도·장소 데이터: 국내 지도 서비스 제공사', '고객 문의 응대: 국내 고객지원 솔루션 제공사'] },
      { h: '7. 이용자의 권리', p: '회원은 언제든 자신의 정보를 열람·수정할 수 있고, 게시물의 공개 범위를 바꾸거나 삭제할 수 있습니다. 처리 정지와 탈퇴 요청은 설정에서 바로 할 수 있으며, 요청은 지체 없이 처리합니다.' },
      { h: '8. 안전성 확보 조치', p: '전송 구간 암호화(TLS), 저장 데이터 암호화, 접근 권한 최소화와 접속 기록 보관을 적용합니다. 사진의 원본 촬영 좌표는 회원이 위치를 공개한 경우에만 노출됩니다.' },
      { h: '9. 문의처', p: '개인정보 보호책임자: 개인정보보호팀 / privacy@spoture.app. 신고나 상담이 필요하면 개인정보침해신고센터(118)에 문의할 수 있습니다.' }
    ]
  }
};

function LegalBody({ docs }) {
  return (
    <React.Fragment>
      <div style={{ background: 'var(--surface-1)', borderRadius: 'var(--radius-card)', padding: 18, boxShadow: 'var(--shadow-card)', marginBottom: 14 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12 }}>
          <i className="ti ti-bulb" style={{ fontSize: 17, color: 'var(--text-accent)' }}></i>
          <span style={{ font: 'var(--text-body-strong)' }}>3줄 요약</span>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {docs.summary.map(s => (
            <div key={s} style={{ display: 'flex', gap: 9 }}>
              <i className="ti ti-check" style={{ fontSize: 15, color: 'var(--text-accent)', flexShrink: 0, marginTop: 2 }}></i>
              <span style={{ font: 'var(--text-small)', color: 'var(--text-secondary)', lineHeight: 1.6, textWrap: 'pretty' }}>{s}</span>
            </div>
          ))}
        </div>
      </div>
      <div style={{ background: 'var(--bg-accent)', borderRadius: 'var(--radius-card)', padding: '16px 18px', marginBottom: 18 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
          <i className="ti ti-sparkles" style={{ fontSize: 16, color: 'var(--text-accent)' }}></i>
          <span style={{ font: '600 13px/1 var(--font-family)', color: 'var(--text-accent)', flex: 1 }}>이번 개정에서 바뀐 점</span>
          <span style={{ font: 'var(--text-micro)', color: 'var(--text-accent)', flexShrink: 0 }}>{docs.version}</span>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>
          {docs.changes.map(c => (
            <div key={c} style={{ display: 'flex', gap: 8 }}>
              <span style={{ font: 'var(--text-small)', color: 'var(--text-accent)', flexShrink: 0 }}>·</span>
              <span style={{ font: 'var(--text-small)', color: 'var(--text-primary)', lineHeight: 1.6, textWrap: 'pretty' }}>{c}</span>
            </div>
          ))}
        </div>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
        {docs.body.map(sec => (
          <div key={sec.h}>
            <span style={{ font: 'var(--text-body-strong)', display: 'block', marginBottom: 8 }}>{sec.h}</span>
            {sec.p && <p style={{ font: 'var(--text-caption)', color: 'var(--text-secondary)', lineHeight: 1.75, margin: sec.list ? '0 0 10px' : 0, textWrap: 'pretty' }}>{sec.p}</p>}
            {sec.list && (
              <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                {sec.list.map(l => (
                  <div key={l} style={{ display: 'flex', gap: 9 }}>
                    <span style={{ font: 'var(--text-caption)', color: 'var(--text-muted)', flexShrink: 0 }}>·</span>
                    <span style={{ font: 'var(--text-caption)', color: 'var(--text-secondary)', lineHeight: 1.7, textWrap: 'pretty' }}>{l}</span>
                  </div>
                ))}
              </div>
            )}
          </div>
        ))}
      </div>
    </React.Fragment>
  );
}
window.LegalBody = LegalBody;

function LegalDoc({ nav, kind }) {
  const lp = new URLSearchParams(location.search);
  const k = kind || lp.get('legal') || 'terms';
  const docs = window.legalDocs[k];
  const [tocOpen, setTocOpen] = React.useState(false);
  return (
    <div style={{ flex: '1 1 0%', minHeight: 0, display: 'flex', flexDirection: 'column', position: 'relative' }}>
      <StatusBar />
      <ScreenHeader title={docs.title} sub={docs.sub} onBack={() => nav('settings')} right={<div onClick={() => setTocOpen(true)} style={{ width: 42, height: 42, borderRadius: '50%', background: 'var(--surface-1)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', boxShadow: 'var(--shadow-card)' }}><i className="ti ti-list" style={{ fontSize: 19 }}></i></div>} />
      <div style={{ flex: '1 1 0%', minHeight: 0, overflowY: 'auto', padding: '0 20px 104px' }}>
        <LegalBody docs={docs} />
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 24, padding: '14px 16px', background: 'var(--surface-2)', borderRadius: 'var(--radius-tile)' }}>
          <i className="ti ti-history" style={{ fontSize: 16, color: 'var(--text-muted)', flexShrink: 0 }}></i>
          <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)', flex: 1 }}>{docs.updated}</span>
          <span onClick={() => nav(k === 'terms' ? 'privacy' : 'terms')} style={{ font: '600 12px/1 var(--font-family)', color: 'var(--text-accent)', cursor: 'pointer', flexShrink: 0 }}>{k === 'terms' ? '개인정보처리방침' : '이용약관'}</span>
        </div>
      </div>
      {tocOpen && <LegalTocSheet toc={docs.toc} title={docs.title} onClose={() => setTocOpen(false)} />}
    </div>
  );
}
window.LegalDoc = LegalDoc;

function LegalModal({ kind, onClose }) {
  const { Button } = window.SpotureDesignSystem_f7ad96;
  const [k, setK] = React.useState(kind || 'terms');
  const docs = window.legalDocs[k];
  const scroller = React.useRef(null);
  const swap = (next) => { setK(next); if (scroller.current) scroller.current.scrollTop = 0; };
  return (
    <div style={{ position: 'absolute', inset: 0, zIndex: 60, display: 'flex', flexDirection: 'column', background: 'var(--surface-1)' }}>
      <StatusBar />
      <div style={{ background: 'var(--surface-1)', padding: '6px 16px 14px', boxShadow: 'var(--shadow-card)', flexShrink: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <div onClick={onClose} style={{ width: 40, height: 40, borderRadius: '50%', background: 'var(--surface-2)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', flexShrink: 0 }}><i className="ti ti-x" style={{ fontSize: 19 }}></i></div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <span style={{ font: 'var(--text-heading)', display: 'block' }}>{docs.title}</span>
            <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)' }}>{docs.sub}</span>
          </div>
        </div>
        <div style={{ display: 'flex', gap: 8, marginTop: 14 }}>
          {[['terms', '이용약관'], ['privacy', '개인정보처리방침']].map(([key, label]) => (
            <div key={key} onClick={() => swap(key)} style={{ flex: 1, textAlign: 'center', padding: '10px 0', borderRadius: 'var(--radius-chip)', cursor: 'pointer', background: k === key ? 'var(--bg-ink)' : 'var(--surface-2)', color: k === key ? 'var(--text-on-ink)' : 'var(--text-secondary)', font: '600 13px/1 var(--font-family)' }}>{label}</div>
          ))}
        </div>
      </div>
      <div ref={scroller} style={{ flex: '1 1 0%', minHeight: 0, overflowY: 'auto', padding: '18px 20px 20px', background: 'var(--bg-app)' }}>
        <LegalBody docs={docs} />
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 22, padding: '14px 16px', background: 'var(--surface-2)', borderRadius: 'var(--radius-tile)' }}>
          <i className="ti ti-history" style={{ fontSize: 16, color: 'var(--text-muted)', flexShrink: 0 }}></i>
          <span style={{ font: 'var(--text-micro)', color: 'var(--text-muted)', flex: 1 }}>{docs.updated}</span>
        </div>
      </div>
      <div style={{ flexShrink: 0, background: 'var(--surface-1)', padding: '14px 20px 22px', boxShadow: 'var(--shadow-sheet)' }}>
        <Button variant="primary" onClick={onClose}>확인했어요</Button>
      </div>
    </div>
  );
}
window.LegalModal = LegalModal;

function LegalTocSheet({ toc, title, onClose }) {
  const { BottomSheet } = window.SpotureDesignSystem_f7ad96;
  return (
    <BottomSheet title={title + ' 목차'} onClose={onClose}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
        {toc.map(t => (
          <div key={t} onClick={onClose} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '15px 4px', borderBottom: '1px solid var(--border)', cursor: 'pointer' }}>
            <span style={{ flex: 1, font: 'var(--text-body)' }}>{t}</span>
            <i className="ti ti-chevron-right" style={{ fontSize: 15, color: 'var(--text-muted)', flexShrink: 0 }}></i>
          </div>
        ))}
      </div>
    </BottomSheet>
  );
}
window.LegalTocSheet = LegalTocSheet;
