<?php
$bagMeta = is_array($bagMeta ?? null) ? $bagMeta : [];
$inventoryMap = is_array($inventoryMap ?? null) ? $inventoryMap : [];
$availableBagRows = is_array($availableBagRows ?? null) ? $availableBagRows : [];
$recentIssueRows = is_array($recentIssueRows ?? null) ? $recentIssueRows : [];
$dongCodes = is_array($dongCodes ?? null) ? $dongCodes : [];
$freeDongSet = is_array($freeDongSet ?? null) ? $freeDongSet : [];
$destTypeOptions = is_array($destTypeOptions ?? null) ? $destTypeOptions : ['동사무소', '구청', '기타'];
$defaultDestType = (string) old('bi2_dest_type', (string) ($destTypeOptions[0] ?? '구청'));

$oldItemCodes = old('item_bag_code');
$oldItemQtys = old('item_qty');
$oldItemPacks = old('item_pack');
$oldItemCodes = is_array($oldItemCodes) ? $oldItemCodes : [];
$oldItemQtys = is_array($oldItemQtys) ? $oldItemQtys : [];
$oldItemPacks = is_array($oldItemPacks) ? $oldItemPacks : [];

$initialRows = [];
$oldCount = max(count($oldItemCodes), count($oldItemQtys), count($oldItemPacks));
for ($i = 0; $i < $oldCount; $i++) {
    $initialRows[] = [
        'code' => trim((string) ($oldItemCodes[$i] ?? '')),
        'qty' => max(0, (int) ($oldItemQtys[$i] ?? 0)),
        'pack' => (string) ($oldItemPacks[$i] ?? 'sheet'),
    ];
}
if ($initialRows === []) {
    $initialRows[] = ['code' => '', 'qty' => 0, 'pack' => 'sheet'];
}
?>

<section class="border-b border-gray-300 p-2 shrink-0 bg-control-panel">
  <span class="text-sm font-bold text-gray-700">무료용 불출 처리</span>
</section>

<div class="border border-gray-300 rounded-lg p-3 mt-2 bg-white">
  <form action="<?= base_url('bag/issue/store') ?>" method="POST" class="space-y-3" id="bag-issue-form">
    <?= csrf_field() ?>

    <div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-6 gap-2 text-sm">
      <div class="flex items-center gap-2 min-w-0">
        <label class="font-bold text-gray-700 whitespace-nowrap shrink-0">불출년도</label>
        <input class="border border-gray-300 rounded px-2 py-1 w-24 max-w-full text-right" name="bi2_year" type="number" min="2000" max="2099" value="<?= esc(old('bi2_year', date('Y'))) ?>" required/>
      </div>
      <div class="flex items-center gap-2 min-w-0">
        <label class="font-bold text-gray-700 whitespace-nowrap shrink-0">분기</label>
        <select class="border border-gray-300 rounded px-2 py-1 w-24 max-w-full" name="bi2_quarter" required>
          <option value="1" <?= old('bi2_quarter', (string) ceil((int) date('n') / 3)) === '1' ? 'selected' : '' ?>>1/4</option>
          <option value="2" <?= old('bi2_quarter', (string) ceil((int) date('n') / 3)) === '2' ? 'selected' : '' ?>>2/4</option>
          <option value="3" <?= old('bi2_quarter', (string) ceil((int) date('n') / 3)) === '3' ? 'selected' : '' ?>>3/4</option>
          <option value="4" <?= old('bi2_quarter', (string) ceil((int) date('n') / 3)) === '4' ? 'selected' : '' ?>>4/4</option>
        </select>
      </div>
      <div class="flex items-center gap-2 min-w-0">
        <label class="font-bold text-gray-700 whitespace-nowrap shrink-0">불출구분</label>
        <select class="border border-gray-300 rounded px-2 py-1 w-28 max-w-full" name="bi2_issue_type" id="bi2_issue_type" required>
          <option value="무료용" <?= old('bi2_issue_type', '무료용') === '무료용' ? 'selected' : '' ?>>무료용</option>
          <option value="공공용" <?= old('bi2_issue_type') === '공공용' ? 'selected' : '' ?>>공공용</option>
        </select>
      </div>
      <div class="flex items-center gap-2 min-w-0">
        <label class="font-bold text-gray-700 whitespace-nowrap shrink-0">불출일</label>
        <input class="border border-gray-300 rounded px-2 py-1 w-36 max-w-full" name="bi2_issue_date" type="date" value="<?= esc(old('bi2_issue_date', date('Y-m-d'))) ?>" required/>
      </div>
      <div class="flex items-center gap-2 min-w-0">
        <label class="font-bold text-gray-700 whitespace-nowrap shrink-0">불출처구분</label>
        <select class="border border-gray-300 rounded px-2 py-1 w-28 max-w-full" name="bi2_dest_type" id="bi2_dest_type">
          <?php foreach ($destTypeOptions as $option): ?>
          <option value="<?= esc($option) ?>" <?= $defaultDestType === $option ? 'selected' : '' ?>><?= esc($option) ?></option>
          <?php endforeach; ?>
        </select>
      </div>
      <div class="flex items-center gap-2 min-w-0 md:col-span-2 xl:col-span-2">
        <label class="font-bold text-gray-700 whitespace-nowrap shrink-0">불출처(동)</label>
        <select class="border border-gray-300 rounded px-2 py-1 w-full min-w-[20rem]" id="bi2_dest_name" name="bi2_dest_name" required>
          <option value="">선택</option>
          <?php foreach ($dongCodes as $dong): ?>
          <?php $dCode = (string) ($dong->cd_code ?? ''); ?>
          <?php $dName = (string) ($dong->cd_name ?? $dCode); ?>
          <?php $hasFree = isset($freeDongSet[$dCode]); ?>
          <?php $oldDest = (string) old('bi2_dest_name'); ?>
          <option
            value="<?= esc($dName) ?>"
            data-dong-code="<?= esc($dCode) ?>"
            data-has-free="<?= $hasFree ? '1' : '0' ?>"
            <?= $oldDest === $dName ? 'selected' : '' ?>
          >
            <?= esc($dName) ?><?= $hasFree ? ' (무료용 가능)' : ' (무료용 없음)' ?>
          </option>
          <?php endforeach; ?>
        </select>
        <input type="hidden" name="bi2_dest_dong_code" id="bi2_dest_dong_code" value="<?= esc((string) old('bi2_dest_dong_code')) ?>" />
      </div>
    </div>

    <div class="border border-gray-300 rounded p-2 bg-gray-50 space-y-2">
      <div class="flex flex-wrap items-center gap-2 text-sm">
        <label class="font-bold text-gray-700">바코드 스캔</label>
        <input
          id="barcode_input"
          type="text"
          class="border border-gray-300 rounded px-2 py-1 w-72"
          placeholder="스캐너로 바코드를 입력 후 Enter"
          autocomplete="off"
        />
        <button type="button" id="add-row-btn" class="border border-gray-300 text-gray-700 px-3 py-1 rounded-sm hover:bg-white">행 추가</button>
        <span class="text-xs text-gray-500">동일 바코드 연속 스캔은 무시됩니다.</span>
      </div>
      <div class="text-xs text-gray-600">
        입고 재고가 있는 봉투/스티커만 불출 가능합니다. 저장 시 포장단위가 낱장으로 환산되어 재고가 차감됩니다.
      </div>
    </div>

    <div class="border border-gray-300 rounded-lg p-4 overflow-auto">
      <table class="w-full data-table text-sm" id="issue-item-table">
        <thead>
          <tr>
            <th class="w-14 text-center">No</th>
            <th class="w-44">봉투코드</th>
            <th>봉투종류</th>
            <th class="w-28 text-right">수량</th>
            <th class="w-28">포장</th>
            <th class="w-32 text-right">재고(낱장)</th>
            <th class="w-36 text-right">환산(낱장)</th>
            <th class="w-20 text-center">작업</th>
          </tr>
        </thead>
        <tbody id="issue-item-body"></tbody>
        <tfoot>
          <tr class="bg-gray-50 font-semibold">
            <td colspan="6" class="text-right pr-2">합계(환산 낱장)</td>
            <td class="text-right pr-2" id="sum_sheet_qty">0</td>
            <td></td>
          </tr>
        </tfoot>
      </table>
    </div>

    <div class="flex gap-2 pt-2">
      <button type="submit" class="bg-btn-search text-white px-6 py-1.5 rounded-sm text-sm shadow hover:opacity-90 transition">저장</button>
      <a href="<?= base_url('bag/issue/cancel') ?>" class="bg-gray-200 text-gray-700 px-6 py-1.5 rounded-sm text-sm hover:bg-gray-300 transition">취소</a>
    </div>
  </form>
</div>

<div class="grid grid-cols-1 xl:grid-cols-2 gap-2 mt-2">
  <section class="border border-gray-300 rounded-lg overflow-hidden bg-white">
    <div class="border-b border-gray-300 bg-gray-50 px-2 py-1 text-sm font-bold text-gray-700">불출 가능 봉투(현재 재고)</div>
    <div class="overflow-auto max-h-[300px]">
      <table class="w-full data-table text-sm">
        <thead>
          <tr>
            <th class="w-12 text-center">No</th>
            <th class="w-28 text-center">봉투코드</th>
            <th>봉투명</th>
            <th class="w-24 text-right">재고(낱장)</th>
            <th class="w-24 text-right">팩당 낱장</th>
            <th class="w-24 text-right">박스당 낱장</th>
          </tr>
        </thead>
        <tbody>
          <?php if ($availableBagRows !== []): ?>
          <?php foreach ($availableBagRows as $idx => $row): ?>
          <tr>
            <td class="text-center"><?= $idx + 1 ?></td>
            <td class="text-center"><?= esc((string) ($row['bag_code'] ?? '')) ?></td>
            <td class="pl-2"><?= esc((string) ($row['bag_name'] ?? '')) ?></td>
            <td class="text-right pr-2"><?= number_format((int) ($row['inventory_qty'] ?? 0)) ?></td>
            <td class="text-right pr-2"><?= number_format((int) ($row['pack_per_sheet'] ?? 1)) ?></td>
            <td class="text-right pr-2"><?= number_format((int) ($row['total_per_box'] ?? 1)) ?></td>
          </tr>
          <?php endforeach; ?>
          <?php else: ?>
          <tr>
            <td colspan="6" class="text-center text-gray-400 py-4">불출 가능한 재고가 없습니다.</td>
          </tr>
          <?php endif; ?>
        </tbody>
      </table>
    </div>
  </section>

  <section class="border border-gray-300 rounded-lg overflow-hidden bg-white">
    <div class="border-b border-gray-300 bg-gray-50 px-2 py-1 text-sm font-bold text-gray-700">최근 불출 내역</div>
    <div class="overflow-auto max-h-[300px]">
      <table class="w-full data-table text-sm">
        <thead>
          <tr>
            <th class="w-12 text-center">No</th>
            <th class="w-24 text-center">불출일</th>
            <th class="w-20 text-center">구분</th>
            <th class="w-28">불출처</th>
            <th class="w-24 text-center">봉투코드</th>
            <th>봉투명</th>
            <th class="w-24 text-right">수량(낱장)</th>
            <th class="w-16 text-center">상태</th>
          </tr>
        </thead>
        <tbody>
          <?php if ($recentIssueRows !== []): ?>
          <?php foreach ($recentIssueRows as $idx => $row): ?>
          <tr>
            <td class="text-center"><?= $idx + 1 ?></td>
            <td class="text-center"><?= esc((string) ($row->bi2_issue_date ?? '')) ?></td>
            <td class="text-center"><?= esc((string) ($row->bi2_issue_type ?? '')) ?></td>
            <td class="pl-2"><?= esc((string) ($row->bi2_dest_name ?? '')) ?></td>
            <td class="text-center"><?= esc((string) ($row->bi2_bag_code ?? '')) ?></td>
            <td class="pl-2"><?= esc((string) ($row->bi2_bag_name ?? '')) ?></td>
            <td class="text-right pr-2"><?= number_format((int) ($row->bi2_qty ?? 0)) ?></td>
            <td class="text-center">
              <?php if ((string) ($row->bi2_status ?? 'normal') === 'cancelled'): ?>
              <span class="text-orange-600">취소</span>
              <?php else: ?>
              정상
              <?php endif; ?>
            </td>
          </tr>
          <?php endforeach; ?>
          <?php else: ?>
          <tr>
            <td colspan="8" class="text-center text-gray-400 py-4">최근 불출 내역이 없습니다.</td>
          </tr>
          <?php endif; ?>
        </tbody>
      </table>
    </div>
  </section>
</div>

<script>
(() => {
  const bagMeta = <?= json_encode($bagMeta, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
  const initialRows = <?= json_encode($initialRows, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
  const knownCodes = Object.keys(bagMeta);
  const body = document.getElementById('issue-item-body');
  const sumSheetQtyEl = document.getElementById('sum_sheet_qty');
  const barcodeInput = document.getElementById('barcode_input');
  const addRowBtn = document.getElementById('add-row-btn');
  const issueTypeEl = document.getElementById('bi2_issue_type');
  const destTypeEl = document.getElementById('bi2_dest_type');
  const destNameEl = document.getElementById('bi2_dest_name');
  const destDongCodeEl = document.getElementById('bi2_dest_dong_code');
  const form = document.getElementById('bag-issue-form');
  let lastScannedCode = '';
  const rows = [];

  const createBagTypeOptions = (selectedCode) => {
    const opts = ['<option value="">선택</option>'];
    knownCodes.forEach((code) => {
      const name = bagMeta[code]?.name || code;
      opts.push(`<option value="${code}" ${code === selectedCode ? 'selected' : ''}>${code} - ${name}</option>`);
    });
    return opts.join('');
  };

  const resolveBagCode = (raw) => {
    const src = String(raw || '').trim();
    if (src === '') return '';
    if (bagMeta[src]) return src;

    const noSpace = src.replace(/\s+/g, '');
    if (bagMeta[noSpace]) return noSpace;

    const compact = noSpace.replace(/[^0-9A-Za-z]/g, '');
    if (bagMeta[compact]) return compact;

    for (const code of knownCodes) {
      if (compact.includes(code)) {
        return code;
      }
    }
    return '';
  };

  const toSheetQty = (code, qty, pack) => {
    const n = Math.max(0, parseInt(String(qty || 0), 10) || 0);
    const meta = bagMeta[code] || { packPerSheet: 1, totalPerBox: 1 };
    if (pack === 'box') return n * Math.max(1, parseInt(meta.totalPerBox, 10) || 1);
    if (pack === 'pack') return n * Math.max(1, parseInt(meta.packPerSheet, 10) || 1);
    return n;
  };

  const recompute = () => {
    let sum = 0;
    rows.forEach((row, idx) => {
      const tr = row.tr;
      tr.querySelector('.col-no').textContent = String(idx + 1);
      const code = row.codeInput.value.trim();
      const qty = row.qtyInput.value;
      const pack = row.packSelect.value;
      const sheetQty = toSheetQty(code, qty, pack);
      const invQty = parseInt((bagMeta[code]?.inventoryQty || 0), 10) || 0;
      row.invCell.textContent = new Intl.NumberFormat('ko-KR').format(invQty);
      row.sheetCell.textContent = new Intl.NumberFormat('ko-KR').format(sheetQty);
      if (code && sheetQty > invQty) {
        row.sheetCell.classList.add('text-red-600', 'font-semibold');
      } else {
        row.sheetCell.classList.remove('text-red-600', 'font-semibold');
      }
      sum += sheetQty;
    });
    sumSheetQtyEl.textContent = new Intl.NumberFormat('ko-KR').format(sum);
  };

  const syncCode = (row, code, setAsUserSelection = false) => {
    const resolved = resolveBagCode(code);
    if (resolved === '') return false;
    row.codeInput.value = resolved;
    row.typeSelect.value = resolved;
    if (setAsUserSelection || row.packSelect.value === '') {
      row.packSelect.value = (bagMeta[resolved]?.totalPerBox || 1) > 1 ? 'box' : 'sheet';
    }
    recompute();
    return true;
  };

  const addRow = (seed = {}) => {
    const tr = document.createElement('tr');
    tr.innerHTML = `
      <td class="text-center col-no"></td>
      <td class="px-1 py-1">
        <input type="text" name="item_bag_code[]" class="code-input border border-gray-300 rounded px-2 py-1 w-full text-sm" value="" placeholder="봉투코드"/>
      </td>
      <td class="px-1 py-1">
        <select name="item_bag_type[]" class="type-select border border-gray-300 rounded px-2 py-1 w-full text-sm">
          ${createBagTypeOptions('')}
        </select>
      </td>
      <td class="px-1 py-1">
        <input type="number" min="0" step="1" name="item_qty[]" class="qty-input border border-gray-300 rounded px-2 py-1 w-full text-sm text-right" value="0"/>
      </td>
      <td class="px-1 py-1">
        <select name="item_pack[]" class="pack-select border border-gray-300 rounded px-2 py-1 w-full text-sm">
          <option value="box">박스</option>
          <option value="pack">팩</option>
          <option value="sheet">낱장</option>
        </select>
      </td>
      <td class="text-right pr-2 inv-cell">0</td>
      <td class="text-right pr-2 sheet-cell">0</td>
      <td class="text-center">
        <button type="button" class="remove-btn text-red-600 hover:underline text-xs">삭제</button>
      </td>
    `;
    body.appendChild(tr);
    const row = {
      tr,
      codeInput: tr.querySelector('.code-input'),
      typeSelect: tr.querySelector('.type-select'),
      qtyInput: tr.querySelector('.qty-input'),
      packSelect: tr.querySelector('.pack-select'),
      invCell: tr.querySelector('.inv-cell'),
      sheetCell: tr.querySelector('.sheet-cell'),
      removeBtn: tr.querySelector('.remove-btn'),
    };
    rows.push(row);

    row.codeInput.addEventListener('change', () => {
      const ok = syncCode(row, row.codeInput.value, true);
      if (!ok) {
        row.codeInput.value = '';
        row.typeSelect.value = '';
        alert('입고 재고가 있는 봉투코드만 입력할 수 있습니다.');
      }
      recompute();
    });
    row.typeSelect.addEventListener('change', () => {
      row.codeInput.value = row.typeSelect.value;
      recompute();
    });
    row.qtyInput.addEventListener('input', recompute);
    row.packSelect.addEventListener('change', recompute);
    row.removeBtn.addEventListener('click', () => {
      if (rows.length <= 1) return;
      tr.remove();
      const i = rows.indexOf(row);
      if (i >= 0) rows.splice(i, 1);
      recompute();
    });

    if (seed.code) {
      syncCode(row, seed.code, true);
    }
    row.qtyInput.value = String(Math.max(0, parseInt(String(seed.qty || 0), 10) || 0));
    if (['box', 'pack', 'sheet'].includes(String(seed.pack || ''))) {
      row.packSelect.value = String(seed.pack);
    }
    recompute();
    return row;
  };

  const appendScannedRow = (code) => {
    const row = addRow({ code, qty: 1, pack: (bagMeta[code]?.totalPerBox || 1) > 1 ? 'box' : 'sheet' });
    row.qtyInput.focus();
    row.qtyInput.select();
  };

  const syncDestDongCode = () => {
    const opt = destNameEl.options[destNameEl.selectedIndex];
    if (!opt) {
      destDongCodeEl.value = '';
      return;
    }
    destDongCodeEl.value = opt.getAttribute('data-dong-code') || '';
  };

  const updateIssueTypeUi = () => {
    const isPublic = issueTypeEl.value === '공공용';
    if (isPublic) {
      destTypeEl.value = '구청';
    }
  };

  addRowBtn.addEventListener('click', () => addRow({ code: '', qty: 0, pack: 'sheet' }));

  barcodeInput.addEventListener('keydown', (event) => {
    if (event.key !== 'Enter') return;
    event.preventDefault();
    const resolved = resolveBagCode(barcodeInput.value);
    barcodeInput.value = '';
    if (!resolved) {
      alert('인식 가능한 봉투코드가 아닙니다.');
      return;
    }
    if (resolved === lastScannedCode) {
      return;
    }
    lastScannedCode = resolved;
    appendScannedRow(resolved);
  });

  destNameEl.addEventListener('change', syncDestDongCode);
  issueTypeEl.addEventListener('change', updateIssueTypeUi);

  form.addEventListener('submit', (event) => {
    syncDestDongCode();
    updateIssueTypeUi();

    const validRows = rows.filter((row) => {
      const code = resolveBagCode(row.codeInput.value);
      const qty = parseInt(row.qtyInput.value || '0', 10) || 0;
      return code !== '' && qty > 0;
    });
    if (validRows.length === 0) {
      event.preventDefault();
      alert('불출 품목을 1건 이상 입력해 주세요.');
      return;
    }

    for (const row of validRows) {
      const code = resolveBagCode(row.codeInput.value);
      const sheetQty = toSheetQty(code, row.qtyInput.value, row.packSelect.value);
      const inv = parseInt((bagMeta[code]?.inventoryQty || 0), 10) || 0;
      if (sheetQty > inv) {
        event.preventDefault();
        alert(`재고 부족: ${code} (재고 ${inv}, 요청 ${sheetQty})`);
        return;
      }
      row.codeInput.value = code;
      row.typeSelect.value = code;
    }

    if (issueTypeEl.value === '무료용') {
      const selected = destNameEl.options[destNameEl.selectedIndex];
      const hasFree = selected ? selected.getAttribute('data-has-free') === '1' : false;
      if (!hasFree) {
        event.preventDefault();
        alert('무료용 불출은 "무료용 가능" 불출처(동)만 선택할 수 있습니다.');
      }
    }
  });

  initialRows.forEach((row) => addRow(row));
  if (rows.length > 1 && !initialRows[0]?.code && !initialRows[0]?.qty) {
    rows[0].tr.remove();
    rows.shift();
  }
  syncDestDongCode();
  updateIssueTypeUi();
  recompute();
})();
</script>
