import { openModal, closeModal, escapeHtml } from './modal.js';
import { sha256 } from '../store.js';
import { uploadImages } from './image-upload.js';

let _store = null;
let _reviews = [];
let _cfg = null;
const MAX_IMAGES = 3;

// 2026-04-29: 5칸 고정 + 페이지네이션(< 1 2 3 4 5 ••• >) + 셔플 + 아래→위 슬라이드업 (사용자 요청)
const PAGE_SIZE = 5;
let _shuffled = [];
let _page = 1;

function shuffle(arr) {
  const a = [...arr];
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}

function reviewCardHTML(r, delay) {
  const stars = '★'.repeat(r.rating || 5) + '☆'.repeat(5 - (r.rating || 5));
  const imgs = Array.isArray(r.images) ? r.images.filter(Boolean) : [];
  const thumb = !r.is_private && imgs.length
    ? `<div class="review-thumb-wrap"><img class="review-thumb" src="${escapeHtml(imgs[0])}" alt="" loading="lazy">${imgs.length > 1 ? `<span class="review-thumb-count">+${imgs.length - 1}</span>` : ''}</div>`
    : '';
  return `
    <div class="review-card ${r.is_private ? 'is-private' : ''}" data-id="${r.id}" style="animation-delay:${delay}ms;">
      ${r.is_private ? '<span class="private-tag">PRIVATE</span>' : ''}
      <div class="stars">${stars}</div>
      <div class="body">${escapeHtml(r.body)}</div>
      ${thumb}
      <div class="author">— ${escapeHtml(r.author)}</div>
    </div>
  `;
}

function totalPages() {
  return Math.max(1, Math.ceil(_shuffled.length / PAGE_SIZE));
}

// 페이지 번호 목록 생성: 양쪽 1+현재 주변 1, ellipsis '...' 삽입
function buildPageNums(current, total) {
  const out = [];
  const pushed = new Set();
  const push = (n) => { if (n >= 1 && n <= total && !pushed.has(n)) { out.push(n); pushed.add(n); } };
  push(1);
  for (let n = current - 1; n <= current + 1; n++) push(n);
  push(total);
  out.sort((a, b) => a - b);
  const result = [];
  for (let i = 0; i < out.length; i++) {
    if (i > 0 && out[i] - out[i - 1] > 1) result.push('…');
    result.push(out[i]);
  }
  return result;
}

function renderPagination() {
  const wrap = document.getElementById('review-more-wrap');
  if (!wrap) return;
  const total = totalPages();
  if (total <= 1) { wrap.innerHTML = ''; return; }
  const nums = buildPageNums(_page, total);
  const btn = (label, target, opts = {}) => {
    const disabled = opts.disabled ? 'opacity:.35;pointer-events:none;' : '';
    const active = opts.active ? 'background:var(--neon-amber);color:#000;border-color:var(--neon-amber);' : '';
    const base = 'min-width:36px;height:36px;padding:0 10px;background:transparent;border:1px solid var(--border-subtle);color:var(--text-secondary);font-family:var(--font-display);font-weight:700;letter-spacing:1px;cursor:pointer;border-radius:4px;display:inline-flex;align-items:center;justify-content:center;';
    return `<button class="review-page" data-page="${target}" type="button" style="${base}${active}${disabled}">${label}</button>`;
  };
  const items = [];
  items.push(btn('‹', _page - 1, { disabled: _page <= 1 }));
  for (const n of nums) {
    if (n === '…') items.push(`<span style="color:var(--text-muted);padding:0 6px;">…</span>`);
    else items.push(btn(String(n), n, { active: n === _page }));
  }
  items.push(btn('›', _page + 1, { disabled: _page >= total }));
  wrap.innerHTML = `
    <div style="margin-top:24px;display:flex;gap:6px;justify-content:center;flex-wrap:wrap;">
      ${items.join('')}
    </div>
  `;
  wrap.querySelectorAll('.review-page').forEach(el => {
    el.addEventListener('click', () => {
      const target = Number(el.dataset.page);
      if (Number.isFinite(target)) goToPage(target);
    });
  });
}

function renderPage(animate) {
  const root = document.getElementById('review-grid');
  if (!root) return;
  const start = (_page - 1) * PAGE_SIZE;
  const slice = _shuffled.slice(start, start + PAGE_SIZE);
  const html = slice.map((r, i) => reviewCardHTML(r, animate ? (i * 90) : 0)).join('');
  root.innerHTML = html;
  renderPagination();
}

function goToPage(n) {
  const total = totalPages();
  const next = Math.min(Math.max(1, n), total);
  if (next === _page) return;
  _page = next;
  renderPage(true);
  // 후기 섹션 상단으로 스크롤 보정
  const grid = document.getElementById('review-grid');
  if (grid) {
    const rect = grid.getBoundingClientRect();
    const offset = window.scrollY + rect.top - 120;
    window.scrollTo({ top: offset, behavior: 'smooth' });
  }
}

export function renderReviews(reviews) {
  _reviews = reviews;
  _shuffled = shuffle(reviews);
  _page = 1;
  const root = document.getElementById('review-grid');
  if (!root) return;
  if (!reviews.length) {
    root.innerHTML = `<div style="grid-column:1/-1;text-align:center;color:var(--text-muted);padding:40px;">아직 등록된 후기가 없습니다.</div>`;
    const wrap = document.getElementById('review-more-wrap');
    if (wrap) wrap.innerHTML = '';
    return;
  }
  renderPage(true);

  if (!root.dataset.boundClick) {
    root.dataset.boundClick = '1';
    root.addEventListener('click', (e) => {
      const card = e.target.closest('.review-card');
      if (!card) return;
      const id = Number(card.dataset.id);
      const r = _reviews.find(x => x.id === id);
      if (!r) return;
      openReview(r);
    });
  }
}

function openReview(r) {
  if (r.is_private) {
    openModal(`
      <button class="close" data-modal-close>×</button>
      <h3>비공개 후기</h3>
      <div class="body">이 후기는 관리자만 볼 수 있습니다.<br>비밀번호를 입력해주세요.</div>
      <div style="margin-top:20px;">
        <input type="password" id="rv-pw" placeholder="비밀번호" style="width:100%;padding:12px;background:var(--bg-elev1);border:1px solid var(--border-subtle);color:var(--text-primary);border-radius:4px;">
      </div>
      <div class="actions">
        <button class="primary" data-rv-unlock="${r.id}">확인</button>
        <button data-modal-close>취소</button>
      </div>
    `);

    document.querySelector('[data-rv-unlock]').addEventListener('click', async () => {
      const pw = document.getElementById('rv-pw').value;
      const hash = await sha256(pw);
      if (hash === r.password_hash) showReviewBody(r);
      else alert('비밀번호가 일치하지 않습니다.');
    });
    return;
  }
  showReviewBody(r);
}

function showReviewBody(r) {
  const stars = '★'.repeat(r.rating || 5) + '☆'.repeat(5 - (r.rating || 5));
  const imgs = Array.isArray(r.images) ? r.images.filter(Boolean) : [];
  const gallery = imgs.length
    ? `<div class="review-gallery">${imgs.map(u => `<img class="review-gallery__img" src="${escapeHtml(u)}" alt="" loading="lazy">`).join('')}</div>`
    : '';
  openModal(`
    <button class="close" data-modal-close>×</button>
    <h3>후기</h3>
    <div style="font-size:18px;color:var(--neon-amber);letter-spacing:4px;margin-bottom:16px;">${stars}</div>
    <div class="body">${escapeHtml(r.body)}</div>
    ${gallery}
    <div class="meta">
      <span>${escapeHtml(r.author)}</span>
      <span>${formatDate(r.created_at)}</span>
    </div>
    <div class="actions">
      <button class="danger" data-rv-delete="${r.id}">작성자 삭제</button>
      <button data-modal-close>닫기</button>
    </div>
  `);

  document.querySelectorAll('.review-gallery__img').forEach(img => {
    img.addEventListener('click', () => openLightbox(img.src));
  });

  const delBtn = document.querySelector('[data-rv-delete]');
  if (delBtn) delBtn.addEventListener('click', async () => {
    const pw = prompt('작성 시 입력한 비밀번호를 입력하세요.');
    if (!pw) return;
    const result = await _store.removeWithPassword('reviews', r.id, pw);
    if (result.ok) {
      alert('삭제되었습니다.');
      location.reload();
    } else if (result.reason === 'no_password_set') {
      alert('이 후기는 비밀번호가 설정되지 않아 작성자 삭제 불가. 운영자에게 문의해주세요.');
    } else {
      alert('비밀번호가 일치하지 않습니다.');
    }
  });
}

// 라이트박스 — review 갤러리 이미지 클릭 시 큰 화면
function openLightbox(src) {
  const lb = document.createElement('div');
  lb.className = 'review-lightbox';
  lb.innerHTML = `<img src="${src}" alt="">`;
  lb.addEventListener('click', () => lb.remove());
  document.body.appendChild(lb);
}

export function bindReviewForm(store, cfg) {
  _store = store;
  _cfg = cfg || { DEMO_MODE: true, SUPABASE_URL: '', SUPABASE_ANON: '' };
  const btn = document.getElementById('open-review-form');
  if (!btn) return;
  btn.addEventListener('click', () => {
    openModal(`
      <button class="close" data-modal-close>×</button>
      <h3>후기 작성</h3>
      <form id="rv-form" style="display:grid;gap:14px;margin-top:20px;">
        <div>
          <label style="font-family:var(--font-display);font-size:11px;letter-spacing:2px;color:var(--text-muted);text-transform:uppercase;">작성자</label>
          <input name="author" required maxlength="20" style="width:100%;padding:10px;background:var(--bg-elev1);border:1px solid var(--border-subtle);color:var(--text-primary);border-radius:4px;margin-top:6px;">
        </div>
        <div>
          <label style="font-family:var(--font-display);font-size:11px;letter-spacing:2px;color:var(--text-muted);text-transform:uppercase;">평점</label>
          <select name="rating" style="width:100%;padding:10px;background:var(--bg-elev1);border:1px solid var(--border-subtle);color:var(--text-primary);border-radius:4px;margin-top:6px;">
            <option value="5">★★★★★</option><option value="4">★★★★☆</option><option value="3">★★★☆☆</option><option value="2">★★☆☆☆</option><option value="1">★☆☆☆☆</option>
          </select>
        </div>
        <div>
          <label style="font-family:var(--font-display);font-size:11px;letter-spacing:2px;color:var(--text-muted);text-transform:uppercase;">내용</label>
          <textarea name="body" required maxlength="1000" style="width:100%;min-height:120px;padding:10px;background:var(--bg-elev1);border:1px solid var(--border-subtle);color:var(--text-primary);border-radius:4px;margin-top:6px;"></textarea>
        </div>
        <div>
          <label style="font-family:var(--font-display);font-size:11px;letter-spacing:2px;color:var(--text-muted);text-transform:uppercase;">사진 (선택, 최대 ${MAX_IMAGES}장)</label>
          <input id="rv-images" name="images" type="file" accept="image/*" multiple style="width:100%;padding:10px;background:var(--bg-elev1);border:1px solid var(--border-subtle);color:var(--text-primary);border-radius:4px;margin-top:6px;">
          <div id="rv-image-preview" style="display:flex;gap:8px;flex-wrap:wrap;margin-top:8px;"></div>
        </div>
        <div style="display:flex;align-items:center;gap:10px;">
          <input type="checkbox" id="rv-private" name="is_private">
          <label for="rv-private" style="font-size:14px;color:var(--text-secondary);">비공개 후기</label>
        </div>
        <div>
          <label style="font-family:var(--font-display);font-size:11px;letter-spacing:2px;color:var(--text-muted);text-transform:uppercase;">삭제 비밀번호 (선택)</label>
          <input name="password" type="password" maxlength="40" placeholder="작성자 본인 삭제용" style="width:100%;padding:10px;background:var(--bg-elev1);border:1px solid var(--border-subtle);color:var(--text-primary);border-radius:4px;margin-top:6px;">
        </div>
        <button type="submit" id="rv-submit" style="padding:14px;background:var(--neon-red);color:#fff;font-family:var(--font-display);font-weight:900;letter-spacing:4px;border-radius:4px;text-transform:uppercase;">작성하기</button>
      </form>
    `);

    // 파일 선택 시 미리보기 + 최대 3장 제한
    const fileInput = document.getElementById('rv-images');
    const previewWrap = document.getElementById('rv-image-preview');
    fileInput.addEventListener('change', () => {
      previewWrap.innerHTML = '';
      const files = Array.from(fileInput.files || []).slice(0, MAX_IMAGES);
      if ((fileInput.files || []).length > MAX_IMAGES) {
        alert(`사진은 최대 ${MAX_IMAGES}장까지 첨부 가능합니다. 처음 ${MAX_IMAGES}장만 사용됩니다.`);
      }
      files.forEach(f => {
        const reader = new FileReader();
        reader.onload = e => {
          const img = document.createElement('img');
          img.src = e.target.result;
          img.style.cssText = 'width:64px;height:64px;object-fit:cover;border-radius:4px;border:1px solid var(--border-subtle);';
          previewWrap.appendChild(img);
        };
        reader.readAsDataURL(f);
      });
    });

    document.getElementById('rv-form').addEventListener('submit', async (e) => {
      e.preventDefault();
      const submitBtn = document.getElementById('rv-submit');
      const fd = new FormData(e.target);
      const pw = fd.get('password');
      const files = Array.from(fileInput.files || []).slice(0, MAX_IMAGES);
      submitBtn.disabled = true;
      submitBtn.textContent = files.length ? '이미지 업로드 중…' : '등록 중…';
      try {
        const images = await uploadImages(files, _cfg);
        const row = {
          author: fd.get('author'),
          rating: Number(fd.get('rating')),
          body: fd.get('body'),
          is_private: fd.get('is_private') === 'on',
          password_hash: pw ? await sha256(pw) : '',
          images
        };
        await _store.insert('reviews', row);
        alert('후기 등록 완료. 감사합니다!');
        closeModal();
        location.reload();
      } catch (err) {
        submitBtn.disabled = false;
        submitBtn.textContent = '작성하기';
        alert('등록 실패: ' + err.message);
      }
    });
  });
}

function formatDate(iso) {
  if (!iso) return '';
  const d = new Date(iso);
  return `${d.getFullYear()}.${String(d.getMonth()+1).padStart(2,'0')}.${String(d.getDate()).padStart(2,'0')}`;
}
