<?php $startDate = (string) ($startDate ?? ''); $endDate = (string) ($endDate ?? ''); ?>
<section class="border-b border-gray-300 p-2 shrink-0 bg-control-panel">
  <div class="flex flex-wrap items-center justify-between gap-2">
    <span class="text-sm font-bold text-gray-700">주문접수 관리</span>
  </div>
  <form method="get" action="<?= base_url('bag/order/phone/manage') ?>" class="mt-2 flex flex-wrap items-center gap-2 text-sm">
    <label class="font-bold text-gray-700">접수일</label>
    <input type="date" lang="ko" name="start_date" value="<?= esc($startDate, 'attr') ?>" class="border border-gray-300 rounded px-2 py-1 text-sm"/>
    <span class="text-gray-400">~</span>
    <input type="date" lang="ko" name="end_date" value="<?= esc($endDate, 'attr') ?>" class="border border-gray-300 rounded px-2 py-1 text-sm"/>
    <button type="submit" class="bg-btn-search text-white px-3 py-1 rounded-sm text-sm">조회</button>
    <?php if ($startDate !== '' || $endDate !== ''): ?>
    <a href="<?= base_url('bag/order/phone/manage') ?>" class="border border-gray-300 text-gray-600 px-3 py-1 rounded-sm text-sm hover:bg-gray-50">초기화</a>
    <?php endif; ?>
  </form>
</section>

<div class="grid grid-cols-1 xl:grid-cols-9 gap-3 mt-2">
  <section class="xl:col-span-5 border border-gray-300 rounded-lg bg-white overflow-hidden flex flex-col">
    <div class="px-3 py-2 border-b border-gray-200 bg-gray-50 text-sm font-semibold text-gray-700">접수 리스트(전화)</div>
    <div id="list-scroll" class="overflow-auto">
      <table class="w-full data-table text-sm">
        <thead>
          <tr>
            <th class="w-12 text-center sort-th cursor-pointer select-none" data-sort="so_idx" data-type="num">번호<span class="sort-ind"></span></th>
            <th class="w-24 text-center sort-th cursor-pointer select-none" data-sort="so_order_date" data-type="str">접수일<span class="sort-ind"></span></th>
            <th class="w-24 text-center sort-th cursor-pointer select-none" data-sort="so_delivery_date" data-type="str">배달일<span class="sort-ind"></span></th>
            <th class="w-14 text-center sort-th cursor-pointer select-none" data-sort="so_channel" data-type="str">구분<span class="sort-ind"></span></th>
            <th class="text-left sort-th cursor-pointer select-none" data-sort="so_ds_name" data-type="str">판매소<span class="sort-ind"></span></th>
            <th class="w-16 text-center sort-th cursor-pointer select-none" data-sort="so_payment_type" data-type="str">결제<span class="sort-ind"></span></th>
            <th class="w-14 text-center sort-th cursor-pointer select-none" data-sort="so_received" data-type="num">포장<span class="sort-ind"></span></th>
            <th class="w-14 text-center sort-th cursor-pointer select-none" data-sort="so_paid" data-type="num">입금<span class="sort-ind"></span></th>
            <th class="w-24 text-right sort-th cursor-pointer select-none" data-sort="so_total_amount" data-type="num">총금액<span class="sort-ind"></span></th>
            <th class="w-14 text-center sort-th cursor-pointer select-none" data-sort="so_status" data-type="str">취소<span class="sort-ind"></span></th>
          </tr>
        </thead>
        <tbody id="order-list-body"></tbody>
      </table>
    </div>
    <div id="list-summary" class="px-3 py-2 border-t border-gray-200 bg-gray-50 text-sm font-semibold text-gray-700 flex flex-wrap items-center justify-between gap-2">
      <span>건수 <span id="list-sum-count" class="text-blue-700">0</span>건</span>
      <span>금액 <span id="list-sum-amount" class="text-blue-700">0</span>원</span>
    </div>
  </section>

  <section id="detail-card" class="xl:col-span-4 border border-gray-300 rounded-lg bg-white overflow-hidden">
    <div class="px-3 py-2 border-b border-gray-200 bg-gray-50 text-sm font-semibold text-gray-700">지정판매소 정보</div>

    <form id="order-detail-form" action="<?= base_url('bag/order/phone/manage/update') ?>" method="POST" class="p-3 space-y-3">
      <?= csrf_field() ?>
      <input type="hidden" name="so_idx" id="detail-so-idx" value=""/>

      <div class="border border-gray-200 rounded-lg p-3 bg-gray-50 text-sm">
        <div class="grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-1">
          <div><span class="font-semibold text-gray-700 inline-block w-20">접수번호</span> <span id="detail-so-no">-</span></div>
          <div><span class="font-semibold text-gray-700 inline-block w-20">판매소코드</span> <span id="detail-shop-code">-</span></div>
          <div><span class="font-semibold text-gray-700 inline-block w-20">판매소명</span> <span id="detail-shop-name">-</span></div>
          <div><span class="font-semibold text-gray-700 inline-block w-20">담당자</span> <span id="detail-shop-rep">-</span></div>
          <div><span class="font-semibold text-gray-700 inline-block w-20">전화번호</span> <span id="detail-shop-tel">-</span></div>
          <div><span class="font-semibold text-gray-700 inline-block w-20">결제수단</span> <span id="detail-payment">-</span></div>
          <div class="md:col-span-2"><span class="font-semibold text-gray-700 inline-block w-20">주소</span> <span id="detail-shop-addr">-</span></div>
          <div><span class="font-semibold text-gray-700 inline-block w-20">접수일</span> <span id="detail-order-date">-</span></div>
          <div class="flex items-center"><span class="font-semibold text-gray-700 inline-block w-20">배달일</span>
            <input type="date" lang="ko" name="so_delivery_date" id="detail-delivery-date-input" class="border border-gray-300 rounded px-2 py-0.5 text-sm"/>
          </div>
          <div><span class="font-semibold text-gray-700 inline-block w-20">상태</span> <span id="detail-status">-</span></div>
        </div>
      </div>

      <div class="flex flex-wrap items-center justify-between gap-2 px-1">
        <span class="text-sm font-semibold text-gray-700">접수 품목 내역</span>
        <div class="flex items-center gap-2">
          <button type="submit" id="btn-save" class="bg-btn-search text-white px-3 py-1 rounded-sm text-sm shadow hover:opacity-90" disabled>주문 수정 저장</button>
          <button type="button" id="btn-receipt" class="border border-gray-300 text-gray-700 px-3 py-1 rounded-sm text-sm hover:bg-gray-50" disabled>입금자 영수증 출력</button>
          <button type="submit" id="btn-cancel-order" form="order-cancel-form" class="border border-red-300 text-red-600 px-3 py-1 rounded-sm text-sm hover:bg-red-50" disabled>주문 취소</button>
        </div>
      </div>
      <div class="border border-gray-300 rounded-lg overflow-auto max-h-[179px]">
        <table class="w-full data-table text-sm">
          <thead>
            <tr>
              <th class="w-14 text-center sticky top-0 z-10" style="background:#fff;box-shadow:inset 0 -1px 0 #e5e7eb;">번호</th>
              <th class="text-left sticky top-0 z-10" style="background:#fff;box-shadow:inset 0 -1px 0 #e5e7eb;">품목</th>
              <th class="w-24 text-right sticky top-0 z-10" style="background:#fff;box-shadow:inset 0 -1px 0 #e5e7eb;">단가</th>
              <th class="w-24 text-right sticky top-0 z-10" style="background:#fff;box-shadow:inset 0 -1px 0 #e5e7eb;">접수량</th>
              <th class="w-24 text-right sticky top-0 z-10" style="background:#fff;box-shadow:inset 0 -1px 0 #e5e7eb;">포장량</th>
              <th class="w-28 text-right sticky top-0 z-10" style="background:#fff;box-shadow:inset 0 -1px 0 #e5e7eb;">접수금액</th>
              <th class="w-40 text-right sticky top-0 z-10" style="background:#fff;box-shadow:inset 0 -1px 0 #e5e7eb;">포장단위(박스/팩/낱장)</th>
            </tr>
          </thead>
          <tbody id="detail-items-body">
            <tr>
              <td colspan="7" class="text-center py-6 text-gray-400">왼쪽 리스트에서 주문을 선택해 주세요.</td>
            </tr>
          </tbody>
          <tfoot>
            <tr class="font-semibold bg-gray-50">
              <td colspan="3" class="text-right px-2 py-1">합계</td>
              <td class="text-right px-2 py-1" id="detail-sum-qty">0</td>
              <td class="text-right px-2 py-1" id="detail-sum-packed">0</td>
              <td class="text-right px-2 py-1" id="detail-sum-amount">0</td>
              <td class="text-right px-2 py-1" id="detail-sum-pack">박스=0, 팩=0, 낱장=0</td>
            </tr>
          </tfoot>
        </table>
      </div>

      <div class="mt-3">
        <div class="flex items-center justify-between px-1 mb-1 text-sm">
          <span class="font-semibold text-gray-700">포장 명세</span>
          <span class="text-gray-600">포장량: <span id="packing-total" class="font-bold text-blue-700">0</span> 개</span>
        </div>
        <div class="border border-gray-300 rounded-lg overflow-auto max-h-[179px]">
          <table class="w-full data-table text-sm">
            <thead>
              <tr>
                <th class="w-12 text-center sticky top-0 z-10" style="background:#fff;box-shadow:inset 0 -1px 0 #e5e7eb;">No</th>
                <th class="w-64 text-left sticky top-0 z-10" style="background:#fff;box-shadow:inset 0 -1px 0 #e5e7eb;">봉투종류</th>
                <th class="w-28 text-center sticky top-0 z-10" style="background:#fff;box-shadow:inset 0 -1px 0 #e5e7eb;">봉투코드</th>
                <th class="w-20 text-right sticky top-0 z-10" style="background:#fff;box-shadow:inset 0 -1px 0 #e5e7eb;">수량</th>
                <th class="text-left sticky top-0 z-10" style="background:#fff;box-shadow:inset 0 -1px 0 #e5e7eb;">포장</th>
              </tr>
            </thead>
            <tbody id="packing-body">
              <tr><td colspan="5" class="text-center py-6 text-gray-400">주문을 선택해 주세요.</td></tr>
            </tbody>
          </table>
        </div>
      </div><!-- /포장 명세 -->
    </form>

    <!-- 주문 취소 폼 — 버튼은 접수 품목 내역 타이틀 옆(form 속성으로 연결) -->
    <form id="order-cancel-form" method="POST" class="hidden">
      <?= csrf_field() ?>
    </form>
  </section>
</div>

<script>
(() => {
  const orders = <?= json_encode($orders ?? [], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
  const orderMap = new Map(orders.map((o) => [String(o.so_idx), o]));

  const listBody = document.getElementById('order-list-body');
  const form = document.getElementById('order-detail-form');
  const cancelForm = document.getElementById('order-cancel-form');
  const detailBody = document.getElementById('detail-items-body');
  const inputSoIdx = document.getElementById('detail-so-idx');
  const btnSave = document.getElementById('btn-save');
  const btnCancel = document.getElementById('btn-cancel-order');
  const btnReceipt = document.getElementById('btn-receipt');
  const receiptBase = '<?= base_url('bag/order/phone/receipt') ?>';
  btnReceipt?.addEventListener('click', () => {
    const id = inputSoIdx.value;
    if (!id) return;
    const o = orderMap.get(String(id));
    // 이미 포장(수령)이 완료된 건의 영수증 재발행 시 안내
    if (o && Number(o.so_received) === 1) {
      if (!confirm('포장이 완료된 건입니다.\n그래도 영수증을 다시 출력할까요?')) return;
    }
    window.open(receiptBase + '/' + encodeURIComponent(id), '_blank');
  });

  const nf = (n) => new Intl.NumberFormat('ko-KR').format(n || 0);

  function setHeader(order) {
    var t = function (id, v) { document.getElementById(id).textContent = (v === undefined || v === null || v === '') ? '-' : v; };
    t('detail-so-no', order ? order.so_idx : '');
    t('detail-shop-code', order ? order.ds_shop_no : '');
    t('detail-shop-name', order ? order.so_ds_name : '');
    t('detail-shop-rep', order ? order.ds_rep_name : '');
    t('detail-shop-tel', order ? order.ds_tel : '');
    t('detail-payment', order ? order.so_payment_type : '');
    t('detail-shop-addr', order ? order.ds_addr : '');
    t('detail-order-date', order ? order.so_order_date : '');
    t('detail-status', order ? ((order.so_status === 'cancelled') ? '취소' : '정상') : '');
    // 배달일 — 수정 가능한 date 입력
    var dd = document.getElementById('detail-delivery-date-input');
    if (dd) {
      var v = order && order.so_delivery_date ? String(order.so_delivery_date) : '';
      dd.value = /^\d{4}-\d{2}-\d{2}/.test(v) ? v.slice(0, 10) : '';
      dd.disabled = !order || order.so_status === 'cancelled';
      // 배달일은 접수일 이후로만 선택 가능
      var od = order && order.so_order_date ? String(order.so_order_date).slice(0, 10) : '';
      if (/^\d{4}-\d{2}-\d{2}$/.test(od)) { dd.min = od; } else { dd.removeAttribute('min'); }
    }
  }

  function calcRow(tr) {
    const qtyInput = tr.querySelector('.item-qty-input');
    const qty = Math.max(0, parseInt(qtyInput.value || '0', 10) || 0);
    qtyInput.value = String(qty);

    const unitPrice = parseInt(tr.dataset.unitPrice || '0', 10) || 0;
    const boxSheets = parseInt(tr.dataset.boxSheets || '0', 10) || 0;
    const packSheets = parseInt(tr.dataset.packSheets || '0', 10) || 0;

    let box = 0;
    let pack = 0;
    let sheet = qty;
    if (boxSheets > 0) {
      box = Math.floor(qty / boxSheets);
      const remain = qty % boxSheets;
      if (packSheets > 0) {
        pack = Math.floor(remain / packSheets);
        sheet = remain % packSheets;
      } else {
        sheet = remain;
      }
    } else if (packSheets > 0) {
      pack = Math.floor(qty / packSheets);
      sheet = qty % packSheets;
    }

    const packedInput = tr.querySelector('.item-packed-input');
    const packed = packedInput ? Math.max(0, parseInt(packedInput.value || '0', 10) || 0) : 0;

    const amount = qty * unitPrice;
    tr.querySelector('.item-amount-cell').textContent = nf(amount);
    tr.querySelector('.item-pack-cell').textContent = `박스=${nf(box)}, 팩=${nf(pack)}, 낱장=${nf(sheet)}`;
    return { qty, packed, amount, box, pack, sheet };
  }

  function recalcTotals() {
    let sumQty = 0;
    let sumPacked = 0;
    let sumAmount = 0;
    let sumBox = 0;
    let sumPack = 0;
    let sumSheet = 0;

    detailBody.querySelectorAll('tr.order-item-row').forEach((tr) => {
      const r = calcRow(tr);
      sumQty += r.qty;
      sumPacked += r.packed;
      sumAmount += r.amount;
      sumBox += r.box;
      sumPack += r.pack;
      sumSheet += r.sheet;
    });

    document.getElementById('detail-sum-qty').textContent = nf(sumQty);
    document.getElementById('detail-sum-packed').textContent = nf(sumPacked);
    document.getElementById('detail-sum-amount').textContent = nf(sumAmount);
    document.getElementById('detail-sum-pack').textContent = `박스=${nf(sumBox)}, 팩=${nf(sumPack)}, 낱장=${nf(sumSheet)}`;
  }

  function renderDetail(orderId) {
    const order = orderMap.get(String(orderId));
    if (!order) return;

    inputSoIdx.value = String(order.so_idx || '');
    setHeader(order);
    cancelForm.action = `<?= base_url('bag/order/phone/manage/cancel') ?>/${order.so_idx}`;

    const isCancelled = order.so_status === 'cancelled';
    btnSave.disabled = isCancelled;
    btnCancel.disabled = isCancelled;
    if (btnReceipt) btnReceipt.disabled = false;

    renderPacking(order); // 포장 명세 탭 동기화

    const items = Array.isArray(order.items) ? order.items : [];
    if (items.length === 0) {
      detailBody.innerHTML = '<tr><td colspan="7" class="text-center py-6 text-gray-400">품목 정보가 없습니다.</td></tr>';
      recalcTotals();
      return;
    }

    detailBody.innerHTML = items.map((item, idx) => {
      const itemId = String(item.soi_idx || '');
      const bagName = `${item.soi_bag_code || ''} ${item.soi_bag_name || ''}`.trim();
      const qty = parseInt(item.soi_qty || 0, 10) || 0;
      const packedQty = parseInt(item.soi_packed_qty || 0, 10) || 0;
      const unitPrice = parseInt(item.soi_unit_price || 0, 10) || 0;
      const amount = parseInt(item.soi_amount || 0, 10) || 0;
      const box = parseInt(item.soi_box_count || 0, 10) || 0;
      const pack = parseInt(item.soi_pack_count || 0, 10) || 0;
      const sheet = parseInt(item.soi_sheet_count || 0, 10) || 0;
      const boxSheets = parseInt(item.box_sheets || 0, 10) || 0;
      const packSheets = parseInt(item.pack_sheets || 0, 10) || 0;

      return `
        <tr class="order-item-row" data-unit-price="${unitPrice}" data-box-sheets="${boxSheets}" data-pack-sheets="${packSheets}">
          <td class="text-center">${idx + 1}</td>
          <td class="text-left pl-2">${bagName}</td>
          <td class="text-right pr-2">${nf(unitPrice)}</td>
          <td class="text-right pr-2">
            <input type="number" min="0" class="item-qty-input border border-gray-300 rounded px-2 py-1 w-24 text-right" name="item_qty[${itemId}]" value="${qty}" ${isCancelled ? 'disabled' : ''}/>
          </td>
          <td class="text-right pr-2">
            <input type="number" min="0" class="item-packed-input border border-gray-300 rounded px-2 py-1 w-24 text-right" name="item_packed[${itemId}]" value="${packedQty}" ${isCancelled ? 'disabled' : ''}/>
          </td>
          <td class="text-right pr-2 item-amount-cell">${nf(amount)}</td>
          <td class="text-right pr-2 item-pack-cell">박스=${nf(box)}, 팩=${nf(pack)}, 낱장=${nf(sheet)}</td>
        </tr>
      `;
    }).join('');

    recalcTotals();
    syncListHeight(); // 상세 카드 높이 확정 후 접수 리스트 높이를 맞춘다
  }

  // 접수 리스트 스크롤 높이를 지정판매소 정보(상세) 카드 높이에 맞춘다.
  // offsetHeight는 화면 zoom(텍스트 줄이기)과 무관한 레이아웃 px라, 배율과 상관없이 두 카드가 같은 높이가 되고 하단 공백이 생기지 않는다.
  const listScrollEl = document.getElementById('list-scroll');
  const detailCardEl = document.getElementById('detail-card');
  function syncListHeight() {
    if (!listScrollEl || !detailCardEl) return;
    const listCard = listScrollEl.closest('section');
    const header = listCard ? listCard.firstElementChild : null;
    const summary = document.getElementById('list-summary');
    listScrollEl.style.height = '0px';       // 리스트를 접어 상세 카드의 본래 높이를 측정
    const target = detailCardEl.offsetHeight
      - (header ? header.offsetHeight : 0)
      - (summary ? summary.offsetHeight : 0);
    listScrollEl.style.height = Math.max(160, target) + 'px';
  }
  window.addEventListener('resize', syncListHeight);
  window.addEventListener('storage', function (e) { if (e.key === 'jrj_font_scale') syncListHeight(); });
  if ('ResizeObserver' in window && detailCardEl) {
    new ResizeObserver(function () { syncListHeight(); }).observe(detailCardEl);
  }

  // ── 포장 명세 탭: 주문 품목을 박스/팩/낱장 단위 행으로 펼침 ──────────
  const packingBody = document.getElementById('packing-body');
  const packingTotal = document.getElementById('packing-total');
  function packEsc(s) { return String(s == null ? '' : s).replace(/[&<>]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' }[c])); }
  function renderPacking(order) {
    if (!packingBody) return;
    const items = (Array.isArray(order.items) ? order.items.slice() : [])
      .sort((a, b) => (Number(b.soi_idx) || 0) - (Number(a.soi_idx) || 0)); // 내림차순
    const rows = [];
    let no = 0;
    const addRow = (code, name, qty, unit) => {
      no++;
      rows.push('<tr><td class="text-center">' + no + '</td>'
        + '<td class="text-left pl-2">' + packEsc(code) + ' ' + packEsc(name) + '</td>'
        + '<td class="text-center text-gray-400">-</td>'
        + '<td class="text-right pr-2">' + nf(qty) + '</td>'
        + '<td class="text-left pl-2">' + unit + '</td></tr>');
    };
    items.forEach((it) => {
      const code = it.soi_bag_code || '';
      const name = it.soi_bag_name || '';
      let qty = parseInt(it.soi_qty || 0, 10) || 0;
      const boxSheets = parseInt(it.box_sheets || 0, 10) || 0;
      const packSheets = parseInt(it.pack_sheets || 0, 10) || 0;
      let box = 0, pack = 0, sheet = qty;
      if (boxSheets > 0) {
        box = Math.floor(qty / boxSheets);
        const rem = qty % boxSheets;
        if (packSheets > 0) { pack = Math.floor(rem / packSheets); sheet = rem % packSheets; }
        else { sheet = rem; }
      } else if (packSheets > 0) {
        pack = Math.floor(qty / packSheets); sheet = qty % packSheets;
      }
      for (let i = 0; i < box; i++) { addRow(code, name, boxSheets, '박스'); }
      for (let i = 0; i < pack; i++) { addRow(code, name, packSheets, '팩'); }
      if (sheet > 0) { addRow(code, name, sheet, '낱장'); }
    });
    packingBody.innerHTML = rows.length ? rows.join('')
      : '<tr><td colspan="5" class="text-center py-6 text-gray-400">포장할 품목이 없습니다.</td></tr>';
    if (packingTotal) packingTotal.textContent = String(no);
  }

  // ── 접수 리스트 렌더 + 헤더 클릭 정렬 ──────────────────────────
  let sortKey = 'so_idx', sortDir = 'desc', selectedId = null;
  const esc = (s) => String(s == null ? '' : s).replace(/[&<>]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' }[c]));

  function rowHtml(o) {
    const cancelled = o.so_status === 'cancelled';
    const dDate = o.so_delivery_date ? String(o.so_delivery_date).slice(0, 10) : '';
    const channel = (o.so_channel && o.so_channel !== 'phone') ? o.so_channel : '전화';
    const packed = Number(o.so_received) === 1;
    return `<tr class="order-list-row cursor-pointer hover:bg-blue-50 ${cancelled ? 'bg-gray-50 text-gray-400' : ''} ${String(o.so_idx) === String(selectedId) ? 'bg-blue-100' : ''}" data-order-id="${o.so_idx}">
      <td class="text-center">${o.so_idx}</td>
      <td class="text-center">${esc(o.so_order_date)}</td>
      <td class="text-center">${esc(dDate)}</td>
      <td class="text-center">${esc(channel)}</td>
      <td class="text-left pl-2">${esc(o.so_ds_name)}</td>
      <td class="text-center">${esc(o.so_payment_type || '-')}</td>
      <td class="text-center" style="text-align:center;">${packed ? '<span style="color:#2563eb;font-weight:700;">O</span>' : '<span class="text-gray-400">X</span>'}</td>
      <td class="text-center" style="text-align:center;">${Number(o.so_paid) === 1 ? '<span style="color:#e11d48;font-size:11px;" title="입금">●</span>' : ''}</td>
      <td class="text-right pr-2">${nf(o.so_total_amount || 0)}</td>
      <td class="text-center">${cancelled ? '취소' : '정상'}</td>
    </tr>`;
  }

  function renderList() {
    const th = document.querySelector('.sort-th[data-sort="' + sortKey + '"]');
    const type = th ? th.dataset.type : 'str';
    const arr = orders.slice().sort((a, b) => {
      let va = a[sortKey], vb = b[sortKey];
      if (type === 'num') { va = Number(va || 0); vb = Number(vb || 0); return sortDir === 'asc' ? va - vb : vb - va; }
      va = String(va || ''); vb = String(vb || '');
      return sortDir === 'asc' ? va.localeCompare(vb, 'ko') : vb.localeCompare(va, 'ko');
    });
    listBody.innerHTML = arr.length
      ? arr.map(rowHtml).join('')
      : '<tr><td colspan="10" class="text-center py-8 text-gray-400">전화 주문 데이터가 없습니다.</td></tr>';
    document.querySelectorAll('.sort-th .sort-ind').forEach((s) => { s.textContent = ''; });
    if (th) th.querySelector('.sort-ind').textContent = sortDir === 'asc' ? ' ▲' : ' ▼';

    // 하단 합계 — 취소 주문은 제외
    const normals = arr.filter((o) => o.so_status !== 'cancelled');
    const sumCountEl = document.getElementById('list-sum-count');
    const sumAmountEl = document.getElementById('list-sum-amount');
    if (sumCountEl) sumCountEl.textContent = nf(normals.length);
    if (sumAmountEl) sumAmountEl.textContent = nf(normals.reduce((s, o) => s + (Number(o.so_total_amount) || 0), 0));
  }

  document.querySelectorAll('.sort-th').forEach((th) => {
    th.addEventListener('click', () => {
      const k = th.dataset.sort;
      if (sortKey === k) { sortDir = sortDir === 'asc' ? 'desc' : 'asc'; } else { sortKey = k; sortDir = 'asc'; }
      renderList();
    });
  });

  listBody?.addEventListener('click', (e) => {
    const tr = e.target.closest('.order-list-row');
    if (!tr) return;
    selectedId = tr.dataset.orderId;
    listBody.querySelectorAll('.order-list-row').forEach((row) => row.classList.remove('bg-blue-100'));
    tr.classList.add('bg-blue-100');
    renderDetail(selectedId);
  });

  detailBody?.addEventListener('input', (e) => {
    if (e.target.closest('.item-qty-input') || e.target.closest('.item-packed-input')) {
      recalcTotals();
    }
  });

  cancelForm?.addEventListener('submit', (e) => {
    if (!confirm('해당 주문을 취소 처리하시겠습니까? (삭제되지 않고 상태만 취소로 변경됩니다)')) {
      e.preventDefault();
    }
  });

  form?.addEventListener('submit', (e) => {
    if (!inputSoIdx.value) {
      e.preventDefault();
      alert('수정할 주문을 먼저 선택해 주세요.');
    }
  });

  renderList();
  const firstRow = listBody?.querySelector('.order-list-row');
  if (firstRow) {
    selectedId = firstRow.dataset.orderId;
    firstRow.classList.add('bg-blue-100');
    renderDetail(selectedId);
  }
  syncListHeight();
})();
</script>

<?= view('bag/_dev_all_sales_panel') ?>
