<?php
declare(strict_types=1);
/**
 * 사용자 의견 위젯 — 화면 우하단 플로팅 버튼 + 모달.
 * 보내기 시 화면을 html2canvas 로 캡처해 의견과 함께 전송한다.
 * 필요한 화면(뷰)에서 <?= view('components/feedback_widget') ?> 로 포함.
 */
$apiPath = (string) parse_url(base_url('feedback'), PHP_URL_PATH);
?>
<div id="fbWidget" class="no-print" style="position:fixed;right:16px;bottom:16px;z-index:11000;">
  <button type="button" id="fbOpen" title="이 화면에 대한 의견 보내기"
    style="display:inline-flex;align-items:center;gap:.4rem;background:#243a5e;color:#fff;border:0;border-radius:999px;padding:.6rem .9rem;font-size:.8rem;font-weight:700;box-shadow:0 4px 14px rgba(0,0,0,.25);cursor:pointer;">
    <i class="fa-regular fa-comment-dots"></i> 의견
  </button>
</div>

<!-- 떠 있는(비차단) 의견 창 — 헤더 드래그로 이동, 우하단 모서리로 크기 조절 -->
<div id="fbModal" class="no-print" style="display:none;position:fixed;inset:0;z-index:11001;pointer-events:none;">
  <div id="fbPanel" style="position:fixed;right:16px;bottom:72px;width:380px;height:auto;min-width:300px;min-height:280px;max-width:95vw;max-height:88vh;background:#fff;border-radius:12px;box-shadow:0 10px 40px rgba(0,0,0,.3);overflow:hidden;resize:both;display:flex;flex-direction:column;pointer-events:auto;">
    <div id="fbHead" style="display:flex;align-items:center;justify-content:space-between;padding:.7rem .9rem;background:#1a2b4b;color:#fff;cursor:move;flex-shrink:0;user-select:none;">
      <span style="font-size:.85rem;font-weight:700;"><i class="fa-regular fa-comment-dots"></i> 이 화면 의견 보내기</span>
      <button type="button" id="fbClose" title="닫기" style="background:transparent;border:0;color:#fff;font-size:1.1rem;cursor:pointer;">&times;</button>
    </div>
    <div style="padding:.9rem;flex:1;overflow:auto;display:flex;flex-direction:column;min-height:0;">
      <textarea id="fbContent" maxlength="2000" placeholder="이 화면에서 불편하거나 바꿨으면 하는 점을 자유롭게 적어 주세요."
        style="width:100%;flex:1;min-height:80px;border:1px solid #d1d5db;border-radius:8px;padding:.6rem;font-size:.85rem;resize:none;box-sizing:border-box;"></textarea>
      <div id="fbCount" style="text-align:right;font-size:.7rem;color:#9ca3af;margin-top:.2rem;">0/2000</div>
      <label style="display:flex;align-items:center;gap:.4rem;margin-top:.5rem;font-size:.75rem;color:#6b7280;">
        <input type="checkbox" id="fbShot" checked/> 현재 화면 캡처 첨부
      </label>
      <div style="margin-top:.5rem;">
        <label for="fbFiles" style="display:inline-flex;align-items:center;gap:.35rem;font-size:.75rem;color:#243a5e;border:1px dashed #c7cdd6;border-radius:8px;padding:.4rem .6rem;cursor:pointer;">
          <i class="fa-regular fa-image"></i> 이미지 첨부 (최대 5장)
        </label>
        <input type="file" id="fbFiles" accept="image/*" multiple style="display:none;"/>
        <div id="fbPreview" style="display:flex;flex-wrap:wrap;gap:.3rem;margin-top:.4rem;"></div>
      </div>
      <div id="fbMsg" style="font-size:.75rem;margin-top:.4rem;min-height:1em;"></div>
      <div style="display:flex;justify-content:flex-end;gap:.4rem;margin-top:.5rem;flex-shrink:0;">
        <button type="button" id="fbCancel" style="border:1px solid #d1d5db;background:#fff;border-radius:8px;padding:.45rem .8rem;font-size:.8rem;cursor:pointer;">취소</button>
        <button type="button" id="fbSend" style="border:0;background:#243a5e;color:#fff;border-radius:8px;padding:.45rem .9rem;font-size:.8rem;font-weight:700;cursor:pointer;">보내기</button>
      </div>
    </div>
  </div>
</div>

<script>
(function () {
  var API = location.origin + <?= json_encode($apiPath, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
  var widget = document.getElementById('fbWidget');
  var modal  = document.getElementById('fbModal');
  var content = document.getElementById('fbContent');
  var msg = document.getElementById('fbMsg');
  var sendBtn = document.getElementById('fbSend');
  var shotChk = document.getElementById('fbShot');
  var fileInput = document.getElementById('fbFiles');
  var preview = document.getElementById('fbPreview');
  var counter = document.getElementById('fbCount');
  var attachments = []; // 선택된 이미지 File 목록(최대 5)

  function updateCount() { if (counter) counter.textContent = (content.value || '').length + '/2000'; }
  content.addEventListener('input', updateCount);

  function renderPreview() {
    preview.innerHTML = '';
    attachments.forEach(function (file, i) {
      var url = URL.createObjectURL(file);
      var box = document.createElement('span');
      box.style.cssText = 'position:relative;display:inline-block;';
      box.innerHTML = '<img src="' + url + '" style="width:48px;height:48px;object-fit:cover;border-radius:6px;border:1px solid #e5e7eb;">'
        + '<button type="button" data-i="' + i + '" title="제거" style="position:absolute;top:-6px;right:-6px;width:18px;height:18px;border-radius:50%;border:0;background:#dc2626;color:#fff;font-size:11px;line-height:1;cursor:pointer;">&times;</button>';
      preview.appendChild(box);
    });
  }
  fileInput.addEventListener('change', function () {
    Array.prototype.forEach.call(fileInput.files || [], function (f) {
      if (attachments.length < 5 && /^image\//.test(f.type)) { attachments.push(f); }
    });
    fileInput.value = '';
    renderPreview();
  });
  preview.addEventListener('click', function (e) {
    var b = e.target.closest('button[data-i]');
    if (!b) return;
    attachments.splice(parseInt(b.getAttribute('data-i'), 10), 1);
    renderPreview();
  });

  function open() {
    modal.style.display = 'block'; msg.textContent = '';
    var panel = document.getElementById('fbPanel');
    // 처음 열 때만 우하단 근처를 left/top 기준으로 배치(드래그·리사이즈 동작 일관)
    if (!panel.dataset.positioned) {
      var w = panel.offsetWidth || 380, h = panel.offsetHeight || 320;
      panel.style.left = Math.max(8, window.innerWidth - w - 16) + 'px';
      panel.style.top  = Math.max(8, window.innerHeight - h - 16) + 'px';
      panel.style.right = 'auto'; panel.style.bottom = 'auto';
      panel.dataset.positioned = '1';
    }
    content.focus();
  }
  function close() { modal.style.display = 'none'; }
  document.getElementById('fbOpen').addEventListener('click', open);
  document.getElementById('fbClose').addEventListener('click', close);
  document.getElementById('fbCancel').addEventListener('click', close);

  // 헤더 드래그로 창 이동 (크기 조절은 패널 우하단 모서리 resize:both 가 처리)
  (function () {
    var panel = document.getElementById('fbPanel');
    var head = document.getElementById('fbHead');
    var dragging = false, sx = 0, sy = 0, sl = 0, st = 0;
    // 드래그 중 iframe(예: 지도)이 마우스를 가로채지 않도록 투명 오버레이
    var ov = document.createElement('div');
    ov.style.cssText = 'position:fixed;inset:0;z-index:11002;cursor:move;display:none;';
    document.body.appendChild(ov);

    head.addEventListener('mousedown', function (e) {
      if (e.target.closest('#fbClose')) return;
      e.preventDefault();
      var r = panel.getBoundingClientRect();
      // right/bottom 기준을 left/top 기준으로 전환(드래그 계산 일관성)
      panel.style.left = r.left + 'px'; panel.style.top = r.top + 'px';
      panel.style.right = 'auto'; panel.style.bottom = 'auto';
      sx = e.clientX; sy = e.clientY; sl = r.left; st = r.top;
      dragging = true; ov.style.display = 'block'; document.body.style.userSelect = 'none';
    });
    document.addEventListener('mousemove', function (e) {
      if (!dragging) return;
      var w = panel.offsetWidth, h = panel.offsetHeight;
      var nl = Math.min(Math.max(0, sl + (e.clientX - sx)), window.innerWidth - w);
      var nt = Math.min(Math.max(0, st + (e.clientY - sy)), window.innerHeight - h);
      panel.style.left = nl + 'px'; panel.style.top = nt + 'px';
    });
    document.addEventListener('mouseup', function () {
      if (!dragging) return;
      dragging = false; ov.style.display = 'none'; document.body.style.userSelect = '';
    });
  })();

  // html2canvas 지연 로드
  function ensureH2C(cb) {
    if (typeof html2canvas === 'function') { cb(); return; }
    var s = document.createElement('script');
    s.src = 'https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js';
    s.onload = function () { cb(); };
    s.onerror = function () { cb(); }; // 실패해도 텍스트만 전송
    document.head.appendChild(s);
  }

  function capture(cb) {
    if (!shotChk.checked) { cb(''); return; }
    ensureH2C(function () {
      if (typeof html2canvas !== 'function') { cb(''); return; }
      var prevW = widget.style.display, prevM = modal.style.display;
      widget.style.display = 'none'; modal.style.display = 'none';
      var scale = Math.min(1, 1280 / Math.max(1, window.innerWidth));
      html2canvas(document.body, { scale: scale, useCORS: true, logging: false, backgroundColor: '#ffffff' })
        .then(function (canvas) {
          widget.style.display = prevW; modal.style.display = prevM;
          try { cb(canvas.toDataURL('image/jpeg', 0.7)); } catch (e) { cb(''); }
        })
        .catch(function () { widget.style.display = prevW; modal.style.display = prevM; cb(''); });
    });
  }

  function send() {
    var text = (content.value || '').trim();
    if (!text) { msg.style.color = '#dc2626'; msg.textContent = '의견 내용을 입력해 주세요.'; return; }
    sendBtn.disabled = true; msg.style.color = '#6b7280'; msg.textContent = '전송 중…';
    capture(function (shot) {
      var fd = new FormData();
      fd.append('content', text);
      fd.append('page_url', location.pathname + location.search);
      fd.append('page_title', (document.title || '').slice(0, 200));
      if (shot) fd.append('screenshot', shot);
      attachments.forEach(function (file) { fd.append('files[]', file, file.name); });
      fetch(API, { method: 'POST', body: fd, credentials: 'same-origin' })
        .then(function (r) { return r.json(); })
        .then(function (d) {
          sendBtn.disabled = false;
          if (d && d.ok) {
            msg.style.color = '#059669'; msg.textContent = '의견이 접수되었습니다. 감사합니다.';
            content.value = ''; updateCount();
            attachments.length = 0; renderPreview();
            setTimeout(close, 900);
          } else {
            msg.style.color = '#dc2626'; msg.textContent = (d && d.message) || '전송에 실패했습니다.';
          }
        })
        .catch(function () { sendBtn.disabled = false; msg.style.color = '#dc2626'; msg.textContent = '전송 중 오류가 발생했습니다.'; });
    });
  }
  sendBtn.addEventListener('click', send);
})();
</script>
