<?php
declare(strict_types=1);

require_once __DIR__ . '/../helpers.php';
require_once __DIR__ . '/../auth/_auth.php';

// 未ログインならログインへ
auth_require_login();

// -------- 一覧の下準備（カテゴリ受取 → SQLite接続 → items取得） --------

// カテゴリ受け取り（英数/_/- のみ許可）
$categorySlug = isset($_GET['category']) ? (string)$_GET['category'] : '';
$categorySlug = preg_replace('~[^A-Za-z0-9_\-]+~', '', $categorySlug);

// SQLite 接続（db.php に統一）
require_once __DIR__ . '/../db.php';
$pdo = db();

// 現在の FEATURE_TOPIC（サイト設定）を取得
$featureTopic = '';
try {
    $stFt = $pdo->prepare('SELECT value FROM settings WHERE key = ? LIMIT 1');
    $stFt->execute(['FEATURE_TOPIC']);
    $featureTopic = (string)($stFt->fetchColumn() ?: '');
} catch (Throwable $e) {
    $featureTopic = '';
}

// テーブル（念のため作成）
$pdo->exec('CREATE TABLE IF NOT EXISTS items (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    category   TEXT NOT NULL,
    title      TEXT NOT NULL DEFAULT "",
    body       TEXT NOT NULL DEFAULT "",
    asset_file TEXT NOT NULL DEFAULT "",
    active     INTEGER NOT NULL DEFAULT 1,
    created_at TEXT NOT NULL,
    updated_at TEXT NOT NULL
)');

// 既存DB互換：active列が無い環境向けに後付け（あれば例外→握りつぶし）
try { $pdo->exec('ALTER TABLE items ADD COLUMN active INTEGER NOT NULL DEFAULT 1'); } catch (Throwable $e) {}

// 互換のために定義だけ残す（以降のロジックが参照するため）
$pdoAdmin = null;
$attachedAdminDb = false;

// セッション＆CSRF（未発行なら作成）
if (session_status() !== PHP_SESSION_ACTIVE) { session_start(); }
if (empty($_SESSION['_csrf'])) { $_SESSION['_csrf'] = bin2hex(random_bytes(32)); }

// ---------- 一括削除（選択行） ----------
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['bulk'] ?? '') === 'delete') {
    // CSRF
    $csrf = (string)($_POST['_csrf'] ?? '');
    if ($csrf === '' || !hash_equals($_SESSION['_csrf'] ?? '', $csrf)) {
        http_response_code(400);
        exit('Bad Request: invalid CSRF token');
    }

    // ID配列（整数化）
    $ids = array_filter(array_map('intval', (array)($_POST['ids'] ?? [])), fn($v) => $v > 0);
    if (!$ids) {
        header('Location: ./items.php?category=' . rawurlencode((string)($_POST['category'] ?? ''))
             . '&q='   . rawurlencode((string)($_POST['q'] ?? ''))
             . '&sort=' . rawurlencode((string)($_POST['sort'] ?? ''))
             . '&dir='  . rawurlencode((string)($_POST['dir'] ?? ''))
             . '&per='  . (int)($_POST['per'] ?? 20)
             . '&deleted=0');
        exit;
    }

    // 削除対象の rows 取得（id, category, asset_file）
    $ph = implode(',', array_fill(0, count($ids), '?'));
    $stmtPick = $pdo->prepare('SELECT id, category, asset_file FROM items WHERE id IN (' . $ph . ')');
    $stmtPick->execute($ids);
    $rowsPick = $stmtPick->fetchAll(PDO::FETCH_ASSOC) ?: [];

    // 物理削除対象ファイル名を収集（重複排除）
    $fileSet = []; // ['filename.ext' => true]
    $updir = realpath(__DIR__ . '/../uploads') ?: (__DIR__ . '/../uploads');

    // helpers
    $stCatId = $pdo->prepare('SELECT id FROM categories WHERE slug = ? LIMIT 1');
    $stKeysA = $pdo->prepare('SELECT "key" FROM fields WHERE category_id = ? AND type = "assets"');
    $stIvAll = $pdo->prepare('SELECT field_key, value FROM item_values WHERE item_id = ?');

    foreach ($rowsPick as $rp) {
        $iid  = (int)($rp['id'] ?? 0);
        $slug = (string)($rp['category'] ?? '');
        $afn  = (string)($rp['asset_file'] ?? '');
        if ($afn !== '') { $fileSet[$afn] = true; }

        if ($iid > 0 && $slug !== '') {
            // カテゴリ→assetsキー一覧
            $stCatId->execute([$slug]);
            $cid = (int)$stCatId->fetchColumn();
            if ($cid > 0) {
                $stKeysA->execute([$cid]);
                $keySet = [];
                foreach ($stKeysA->fetchAll(PDO::FETCH_COLUMN) ?: [] as $k) {
                    $k = (string)$k;
                    if ($k !== '') $keySet[$k] = true;
                }
                if (!empty($keySet)) {
                    // 対象アイテムの全値→assetsキーだけ拾う
                    $stIvAll->execute([$iid]);
                    foreach ($stIvAll->fetchAll(PDO::FETCH_ASSOC) ?: [] as $vrow) {
                        $fk = (string)($vrow['field_key'] ?? '');
                        $vv = (string)($vrow['value'] ?? '');
                        if ($vv !== '' && isset($keySet[$fk])) {
                            $fileSet[$vv] = true;
                        }
                    }
                }
            }
        }
    }

    // レコード削除（items / item_values）
    try {
        $stmtDel = $pdo->prepare('DELETE FROM items WHERE id IN (' . $ph . ')');
        $stmtDel->execute($ids);

        $stmtIv = $pdo->prepare('DELETE FROM item_values WHERE item_id IN (' . $ph . ')');
        $stmtIv->execute($ids);
    } catch (\Throwable $e) {
        http_response_code(500);
        exit('Internal Server Error: delete failed');
    }

    // 物理ファイル削除
    foreach (array_keys($fileSet) as $fn) {
        $fn = (string)$fn;
        if ($fn !== '') {
            $path = $updir . '/' . $fn;
            if (is_file($path)) { @unlink($path); }
        }
    }

    // 戻り（絞り込みやソートを保持）
    header('Location: ./items.php?category=' . rawurlencode((string)($_POST['category'] ?? ''))
         . '&q='   . rawurlencode((string)($_POST['q'] ?? ''))
         . '&sort=' . rawurlencode((string)($_POST['sort'] ?? ''))
         . '&dir='  . rawurlencode((string)($_POST['dir'] ?? ''))
         . '&per='  . (int)($_POST['per'] ?? 20)
         . '&deleted=' . count($ids));
    exit;
}

 // 新規作成フォームに前回入力（_flash_form）が残らないようクリア
 unset($_SESSION['_flash_form']);

// 特集トグル（POST）: item_values.PICKUP_TOPIC を FEATURE_TOPIC にセット/解除
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['_action'] ?? '') === 'feature_toggle') {
    // このアイテムのカテゴリにPICKUP_TOPICが無ければ無効化
    $stChk = $pdo->prepare(
        'SELECT 1
           FROM items i
           JOIN categories c ON c.slug = i.category
           JOIN fields f     ON f.category_id = c.id AND f."key" = "PICKUP_TOPIC"
          WHERE i.id = ?
          LIMIT 1'
    );
    $stChk->execute([ (int)($_POST['id'] ?? 0) ]);
    if (!$stChk->fetchColumn()) {
        header('Location: ./items.php?category=' . rawurlencode($categorySlug) . '&ok=1'); // 何もせず戻る
        exit;
    }
    if (session_status() !== PHP_SESSION_ACTIVE) { session_start(); }
    $csrfPost = (string)($_POST['_csrf'] ?? '');
    if ($csrfPost === '' || !hash_equals((string)($_SESSION['_csrf'] ?? ''), $csrfPost)) {
        header('Location: ./items.php?category=' . rawurlencode($categorySlug) . '&err=' . rawurlencode('フォームの有効期限が切れました。もう一度お試しください。'));
        exit;
    }

    $idTgl = max(0, (int)($_POST['id'] ?? 0));
    $toOn  = (int)($_POST['to_on'] ?? 0) === 1;
    if ($idTgl > 0 && $featureTopic !== '') {
        try {
            if ($toOn) {
                // UPDATE → 0件なら INSERT
                $stU = $pdo->prepare('UPDATE item_values SET value = ? WHERE item_id = ? AND field_key = "PICKUP_TOPIC"');
                $stU->execute([$featureTopic, $idTgl]);
                if ($stU->rowCount() === 0) {
                    $stI = $pdo->prepare('INSERT INTO item_values(item_id, field_key, value) VALUES(?, "PICKUP_TOPIC", ?)');
                    $stI->execute([$idTgl, $featureTopic]);
                }
            } else {
                $stD = $pdo->prepare('DELETE FROM item_values WHERE item_id = ? AND field_key = "PICKUP_TOPIC"');
                $stD->execute([$idTgl]);
            }
        } catch (Throwable $e) {
            header('Location: ./items.php?category=' . rawurlencode($categorySlug) . '&err=' . rawurlencode('保存に失敗しました。'));
            exit;
        }
    }
    header('Location: ./items.php?category=' . rawurlencode($categorySlug) . '&ok=1');
    exit;
}

// 公開トグル（POST）
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['_action'] ?? '') === 'toggle') {
    if (session_status() !== PHP_SESSION_ACTIVE) { session_start(); }
    $csrfPost = (string)($_POST['_csrf'] ?? '');
    if ($csrfPost === '' || !hash_equals((string)($_SESSION['_csrf'] ?? ''), $csrfPost)) {
        header('Location: ./items.php?category=' . rawurlencode($categorySlug) . '&err=' . rawurlencode('フォームの有効期限が切れました。もう一度お試しください。'));
        exit;
    }
    $idTgl = max(0, (int)($_POST['id'] ?? 0));
    $toActive = (int)($_POST['to_active'] ?? 0) === 1 ? 1 : 0;
    if ($idTgl > 0) {
        $stmt = $pdo->prepare('UPDATE items SET active=? WHERE id=?');
        $stmt->execute([$toActive, $idTgl]);
    }
    header('Location: ./items.php?category=' . rawurlencode($categorySlug) . '&ok=1');
    exit;
}

// 削除（POST）
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['_action'] ?? '') === 'delete') {
    $csrfPost = (string)($_POST['_csrf'] ?? '');
    if ($csrfPost === '' || !hash_equals((string)($_SESSION['_csrf'] ?? ''), $csrfPost)) {
        header('Location: ./items.php?category=' . rawurlencode($categorySlug) . '&err=' . rawurlencode('フォームの有効期限が切れました。もう一度お試しください。'));
        exit;
    }
    $idDel = max(0, (int)($_POST['id'] ?? 0));
    if ($idDel > 0) {
        // 削除対象の基本情報
        $stPick = $pdo->prepare('SELECT id, category, asset_file FROM items WHERE id = ?');
        $stPick->execute([$idDel]);
        if ($row = $stPick->fetch(PDO::FETCH_ASSOC)) {
            $slug = (string)($row['category'] ?? '');
            $afn  = (string)($row['asset_file'] ?? '');

            $fileSet = [];
            if ($afn !== '') $fileSet[$afn] = true;

            $updir = realpath(__DIR__ . '/../uploads') ?: (__DIR__ . '/../uploads');

            // カテゴリの assets キー → item_values のファイル名を収集
            if ($slug !== '') {
                $stCatId = $pdo->prepare('SELECT id FROM categories WHERE slug = ? LIMIT 1');
                $stCatId->execute([$slug]);
                $cid = (int)$stCatId->fetchColumn();

                if ($cid > 0) {
                    $stKeysA = $pdo->prepare('SELECT "key" FROM fields WHERE category_id = ? AND type = "assets"');
                    $stKeysA->execute([$cid]);
                    $keySet = [];
                    foreach ($stKeysA->fetchAll(PDO::FETCH_COLUMN) ?: [] as $k) {
                        $k = (string)$k;
                        if ($k !== '') $keySet[$k] = true;
                    }

                    if (!empty($keySet)) {
                        $stIvAll = $pdo->prepare('SELECT field_key, value FROM item_values WHERE item_id = ?');
                        $stIvAll->execute([$idDel]);
                        foreach ($stIvAll->fetchAll(PDO::FETCH_ASSOC) ?: [] as $vrow) {
                            $fk = (string)($vrow['field_key'] ?? '');
                            $vv = (string)($vrow['value'] ?? '');
                            if ($vv !== '' && isset($keySet[$fk])) {
                                $fileSet[$vv] = true;
                            }
                        }
                    }
                }
            }

            // レコード削除
            $pdo->prepare('DELETE FROM items WHERE id = ?')->execute([$idDel]);
            $pdo->prepare('DELETE FROM item_values WHERE item_id = ?')->execute([$idDel]);

            // 物理ファイル削除
            foreach (array_keys($fileSet) as $fn) {
                $fn = (string)$fn;
                if ($fn !== '') {
                    $path = $updir . '/' . $fn;
                    if (is_file($path)) { @unlink($path); }
                }
            }
        }
    }
    header('Location: ./items.php?category=' . rawurlencode($categorySlug) . '&ok=1');
    exit;
}

// 一覧データ取得（並び替え・ページング対応）
$allowedSort = ['id', 'active', 'created_at', 'updated_at']; // 公開もソート対象に追加
$sortKey     = isset($_GET['sort']) ? (string)$_GET['sort'] : 'id';
if (!in_array($sortKey, $allowedSort, true)) {
    $sortKey = 'id';
}
$dirRaw = strtolower((string)($_GET['dir'] ?? 'desc'));
$dirSql = ($dirRaw === 'asc') ? 'ASC' : 'DESC';

$page = (int)($_GET['page'] ?? 1);
if ($page < 1) $page = 1;
$per  = (int)($_GET['per'] ?? 20);
if (!in_array($per, [20,50,100], true)) $per = 20;
$offset = ($page - 1) * $per;

// キーワード検索（タイトル部分一致）
$qRaw = (string)($_GET['q'] ?? '');
$q    = mb_substr(trim($qRaw), 0, 100, 'UTF-8'); // 安全のため100文字上限

$idRaw = (string)($_GET['id'] ?? '');
$idEq  = (ctype_digit($idRaw) ? (int)$idRaw : 0); // 数値IDのみ許可（0=無効）

// 共通 WHERE
$where  = '';
$params = [];
if ($categorySlug !== '') {
    $where = ' WHERE category = :category';
    $params[':category'] = $categorySlug;
}

if ($q !== '') {
    $where .= ($where === '' ? ' WHERE ' : ' AND ') . 'title LIKE :q';
    $params[':q'] = '%'.$q.'%';
}

if ($idEq > 0) {
    $where .= ($where === '' ? ' WHERE ' : ' AND ') . 'id = :id';
    $params[':id'] = $idEq;
}

// 件数
$sqlCount = 'SELECT COUNT(*) FROM items' . $where;
$stmtCount = $pdo->prepare($sqlCount);
foreach ($params as $k => $v) { $stmtCount->bindValue($k, $v, PDO::PARAM_STR); }
$stmtCount->execute();
$total = (int)$stmtCount->fetchColumn();
$totalPages = max(1, (int)ceil($total / $per));
if ($page > $totalPages) {
    $page   = $totalPages;
    $offset = ($page - 1) * $per;
}

// データ本体
$selectCols = 'id, category, title, asset_file, active, created_at, updated_at';
$sql = 'SELECT ' . $selectCols . ' FROM items' . $where
     . ' ORDER BY ' . $sortKey . ' ' . $dirSql . ', id DESC'
     . ' LIMIT ' . (int)$per . ' OFFSET ' . (int)$offset;

$stmt = $pdo->prepare($sql);
foreach ($params as $k => $v) { $stmt->bindValue($k, $v, PDO::PARAM_STR); }
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];

// 一覧表示に追加する「list_visible=1」の項目（最大3列）
$listFields = [];
$labelsMap  = []; // [key => [value => label]]
$ivMap      = []; // [item_id => [field_key => value]]

if ($categorySlug !== '') {
    // カテゴリID取得
    $stCid = $pdo->prepare('SELECT id FROM categories WHERE slug = ? LIMIT 1');
    $stCid->execute([$categorySlug]);
    $cid = (int)$stCid->fetchColumn();

    if ($cid > 0) {
        // 表示列（最大3）
        $stF = $pdo->prepare('SELECT "key", label, type, options FROM fields WHERE category_id = ? AND list_visible = 1 ORDER BY ord ASC, id ASC LIMIT 3');
        $stF->execute([$cid]);
        $listFields = $stF->fetchAll(PDO::FETCH_ASSOC) ?: [];

        // ラベル変換（select/radio/checkbox）
        foreach ($listFields as $lf) {
            $k = (string)($lf['key'] ?? '');
            $t = (string)($lf['type'] ?? '');
            $optJ = (string)($lf['options'] ?? '');
            if ($k === '' || $optJ === '') continue;
            if (in_array($t, ['select','radio','checkbox'], true)) {
                $arr = json_decode($optJ, true);
                if (is_array($arr)) {
                    $map = [];
                    foreach ($arr as $o) {
                        $v = isset($o['value']) ? (string)$o['value'] : '';
                        $l = isset($o['label']) ? (string)$o['label'] : $v;
                        if ($v !== '') $map[$v] = $l;
                    }
                    if ($map) $labelsMap[$k] = $map;
                }
            }
        }

        // このページで表示している item_id 群の値をまとめて取得
        if ($rows && $listFields) {
            $ids = array_values(array_filter(array_map(fn($r)=> (int)($r['id'] ?? 0), $rows), fn($v)=> $v>0));
            if ($ids) {
                $ph = implode(',', array_fill(0, count($ids), '?'));
                $stIv = $pdo->prepare('SELECT item_id, field_key, value FROM item_values WHERE item_id IN (' . $ph . ')');
                $stIv->execute($ids);
                foreach ($stIv->fetchAll(PDO::FETCH_ASSOC) ?: [] as $v) {
                    $iid = (int)($v['item_id'] ?? 0);
                    $fk  = (string)($v['field_key'] ?? '');
                    $val = (string)($v['value'] ?? '');
                    if ($iid > 0 && $fk !== '') {
                        if (!isset($ivMap[$iid])) $ivMap[$iid] = [];
                        $ivMap[$iid][$fk] = $val;
                    }
                }
            }
        }
    }
}

$hasPickupTopic = false;
if ($categorySlug !== '' && isset($cid) && (int)$cid > 0) {
    $stHas = $pdo->prepare('SELECT 1 FROM fields WHERE category_id = ? AND "key" = "PICKUP_TOPIC" LIMIT 1');
    $stHas->execute([(int)$cid]);
    $hasPickupTopic = (bool)$stHas->fetchColumn();
}

?><!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>データ一覧｜Template Party CMS</title>
  <link rel="stylesheet" href="<?= h(asset_url('/admin/assets/admin.css', true)) ?>">
</head>
<body class="admin items">
<?php include __DIR__ . '/_header.php'; ?>

<div id="container">
  <h1>データ一覧</h1>

  <?php if (isset($_GET['ok']) && (string)$_GET['ok'] === '1'): ?>
    <p class="ok">保存しました</p>
  <?php elseif (isset($_GET['err']) && (string)$_GET['err'] !== ''): ?>
    <p class="err"><?= htmlspecialchars((string)$_GET['err'], ENT_QUOTES, 'UTF-8') ?></p>
  <?php endif; ?>
  <?php if (isset($_GET['deleted'])): ?><p class="ok">削除しました（<?= (int)$_GET['deleted'] ?>件）</p><?php endif; ?>

  <p class="meta">カテゴリ: <span class="mono"><?= htmlspecialchars($categorySlug !== '' ? $categorySlug : '（全件）', ENT_QUOTES, 'UTF-8') ?></span></p>

  <?php if ($categorySlug !== ''): ?>
  <div class="mb1rem">
    <a class="btn1" href="./regist.php?category=<?= rawurlencode($categorySlug) ?>&id=new">新規作成</a>
  </div>
  <?php endif; ?>

  <form method="get" action="./items.php" class="mb1rem">
    <input type="hidden" name="category" value="<?= htmlspecialchars($categorySlug, ENT_QUOTES, 'UTF-8') ?>">
    <input type="hidden" name="sort"     value="<?= htmlspecialchars($sortKey, ENT_QUOTES, 'UTF-8') ?>">
    <input type="hidden" name="dir"      value="<?= htmlspecialchars($dirRaw, ENT_QUOTES, 'UTF-8') ?>">
    <input type="hidden" name="per"      value="<?= (int)$per ?>">

    <label for="js-q">キーワード：</label>
    <input id="js-q" class="input-default" type="search" name="q"
           value="<?= htmlspecialchars($q, ENT_QUOTES, 'UTF-8') ?>"
           placeholder="タイトルを検索">

    <label for="js-id" style="margin-left:.6rem;">ID：</label>
    <input id="js-id" class="input-default" type="number" name="id" min="1" step="1"
               value="<?= ($idEq > 0 ? (string)$idEq : '') ?>">

    <button type="submit">検索</button>
    <?php if ($q !== '' || ($idEq ?? 0) > 0): ?>
      <a href="./items.php?category=<?= rawurlencode($categorySlug) ?>">クリア</a>
    <?php endif; ?>
  </form>

  <form method="get" action="./items.php" class="mb1rem">
    <input type="hidden" name="category" value="<?= htmlspecialchars($categorySlug, ENT_QUOTES, 'UTF-8') ?>">
    <input type="hidden" name="sort"     value="<?= htmlspecialchars($sortKey, ENT_QUOTES, 'UTF-8') ?>">
    <input type="hidden" name="dir"      value="<?= htmlspecialchars($dirRaw, ENT_QUOTES, 'UTF-8') ?>">
    <input type="hidden" name="q"        value="<?= htmlspecialchars($q, ENT_QUOTES, 'UTF-8') ?>">
    <input type="hidden" name="page"     value="1">
    <label for="js-per">表示件数：</label>
    <select id="js-per" class="input" name="per" onchange="this.form.submit()">
      <option value="20"  <?= ($per===20  ? 'selected' : '') ?>>20件</option>
      <option value="50"  <?= ($per===50  ? 'selected' : '') ?>>50件</option>
      <option value="100" <?= ($per===100 ? 'selected' : '') ?>>100件</option>
    </select>
    <noscript><button type="submit" class="btn1 ml05rem">変更</button></noscript>
  </form>

  <?php if (!$rows): ?>
    <p>データがありません。</p>
  <?php endif; ?>

  <div class="table-wrap">
  
  <!-- 一括削除フォームは分離（ネスト回避） -->
  <form id="bulk-form" method="post" action="./items.php">
    <input type="hidden" name="_csrf"    value="<?= htmlspecialchars($_SESSION['_csrf'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
    <input type="hidden" name="bulk"     value="delete">
    <input type="hidden" name="category" value="<?= htmlspecialchars($categorySlug, ENT_QUOTES, 'UTF-8') ?>">
    <input type="hidden" name="q"        value="<?= htmlspecialchars($q, ENT_QUOTES, 'UTF-8') ?>">
    <input type="hidden" name="sort"     value="<?= htmlspecialchars($sortKey, ENT_QUOTES, 'UTF-8') ?>">
    <input type="hidden" name="dir"      value="<?= htmlspecialchars($dirRaw, ENT_QUOTES, 'UTF-8') ?>">
    <input type="hidden" name="per"      value="<?= (int)$per ?>">
    <input type="hidden" name="id"       value="<?= ($idEq > 0 ? (string)$idEq : '') ?>">
  </form>

    <table class="ta1">
      <thead>
        <tr>
          <th class="checkbox">
            <input type="checkbox" id="js-check-all" onclick="document.querySelectorAll('.js-check').forEach(cb=>cb.checked=this.checked)">
          </th>
          <th class="id">
            <a href="./items.php?category=<?= rawurlencode($categorySlug) ?>&sort=id&dir=<?= ($sortKey==='id' && $dirRaw==='asc') ? 'desc' : 'asc' ?>&q=<?= rawurlencode($q) ?>&id=<?= (int)($idEq ?? 0) ?>&per=<?= (int)$per ?>">
              ID<?= ($sortKey==='id' ? ($dirRaw==='asc' ? '▲' : '▼') : '') ?>
            </a>
          </th>
          <?php if ($categorySlug === ''): ?><th class="category">カテゴリ</th><?php endif; ?>
          <th class="title">タイトル</th>
          <?php if (!empty($listFields)): foreach ($listFields as $lf): ?>
            <th class="slug"><?= h((string)($lf['label'] ?? (string)($lf['key'] ?? ''))) ?></th>
          <?php endforeach; endif; ?>
          <?php if ($hasPickupTopic && $featureTopic !== '' && $categorySlug !== ''): ?>
            <th class="feature">特集</th>
          <?php endif; ?>
          <th class="active">
            <a href="./items.php?category=<?= rawurlencode($categorySlug) ?>&sort=active&dir=<?= ($sortKey==='active' && $dirRaw==='asc') ? 'desc' : 'asc' ?>&q=<?= rawurlencode($q) ?>&id=<?= (int)($idEq ?? 0) ?>&per=<?= (int)$per ?>">
              公開<?= ($sortKey==='active' ? ($dirRaw==='asc' ? '▲' : '▼') : '') ?>
            </a>
          </th>
          <th class="date">
            <a href="./items.php?category=<?= rawurlencode($categorySlug) ?>&sort=created_at&dir=<?= ($sortKey==='created_at' && $dirRaw==='asc') ? 'desc' : 'asc' ?>&q=<?= rawurlencode($q) ?>&id=<?= (int)($idEq ?? 0) ?>&per=<?= (int)$per ?>">
              登録日<?= ($sortKey==='created_at' ? ($dirRaw==='asc' ? '▲' : '▼') : '') ?>
            </a>
          </th>
          <th class="date">
            <a href="./items.php?category=<?= rawurlencode($categorySlug) ?>&sort=updated_at&dir=<?= ($sortKey==='updated_at' && $dirRaw==='asc') ? 'desc' : 'asc' ?>&q=<?= rawurlencode($q) ?>&id=<?= (int)($idEq ?? 0) ?>&per=<?= (int)$per ?>">
              更新日<?= ($sortKey==='updated_at' ? ($dirRaw==='asc' ? '▲' : '▼') : '') ?>
            </a>
          </th>
          <th class="btn-table">操作</th>
        </tr>
      </thead>
      <tbody>
        <?php if ($rows): ?>
          <?php foreach ($rows as $r): ?>
            <?php
              $catForLink = ($categorySlug !== '') ? $categorySlug : (string)($r['category'] ?? '');
              $idForLink  = (int)$r['id'];
              $titleDisp  = htmlspecialchars((string)$r['title'], ENT_QUOTES, 'UTF-8');
              $dateDisp   = htmlspecialchars(substr((string)$r['created_at'], 0, 10), ENT_QUOTES, 'UTF-8');
              $updatedDisp = htmlspecialchars(substr((string)$r['updated_at'], 0, 10), ENT_QUOTES, 'UTF-8');
            ?>
            <tr>
              <td class="checkbox"><input type="checkbox" class="js-check" name="ids[]" value="<?= (int)$r['id'] ?>" form="bulk-form"></td>
              <td class="id"><?= $idForLink ?></td>
              <?php if ($categorySlug === ''): ?>
                <td class="category"><?= htmlspecialchars((string)($r['category'] ?? ''), ENT_QUOTES, 'UTF-8') ?></td>
              <?php endif; ?>
              <td class="title">
                <span class="cell-title">
                  <a href="./regist.php?category=<?= rawurlencode($catForLink) ?>&id=<?= $idForLink ?>"><?= $titleDisp ?></a>
                </span>
              </td>
              <?php if (!empty($listFields)): ?>
                <?php foreach ($listFields as $lf): ?>
                  <?php
                    $k = (string)($lf['key'] ?? '');
                    $t = (string)($lf['type'] ?? '');
                    $raw = (string)($ivMap[$idForLink][$k] ?? '');
                    $disp = '—';
                    if ($raw !== '') {
                        if ($t === 'assets') {
                            $disp = '有';
                        } elseif ($t === 'checkbox') {
                            $parts = array_values(array_filter(array_map('trim', explode(',', $raw)), 'strlen'));
                            if ($parts) {
                                $labels = array_map(function($v) use ($k, $labelsMap){ return (string)($labelsMap[$k][$v] ?? $v); }, $parts);
                                $disp = implode('、', $labels);
                            }
                        } elseif (in_array($t, ['select','radio'], true)) {
                            $disp = (string)($labelsMap[$k][$raw] ?? $raw);
                        } else {
                            $disp = $raw;
                            if (function_exists('mb_substr')) { $disp = mb_substr($disp, 0, 40, 'UTF-8'); }
                            else { if (strlen($disp) > 40) $disp = substr($disp, 0, 40); }
                        }
                    }
                  ?>
                  <td class="slug"><?= h($disp) ?></td>
                <?php endforeach; ?>
              <?php endif; ?>
              <?php
                // この行の特集状態（PICKUP_TOPIC）が現在の FEATURE_TOPIC と一致しているか
                $pickRaw = (string)($ivMap[$idForLink]['PICKUP_TOPIC'] ?? '');
                $isPicked = ($featureTopic !== '' && $pickRaw === $featureTopic);
              ?>
              <?php if ($hasPickupTopic && $featureTopic !== '' && $categorySlug !== ''): ?>
              <td class="feature">
                <?php
                  // この行の特集状態（PICKUP_TOPIC）が現在の FEATURE_TOPIC と一致しているか
                  $pickRaw  = (string)($ivMap[$idForLink]['PICKUP_TOPIC'] ?? '');
                  $isPicked = ($featureTopic !== '' && $pickRaw === $featureTopic);
                ?>
                <?php if ($featureTopic === ''): ?>
                  —
                <?php else: ?>
                  <div class="btns">
                    <form method="post" action="./items.php?category=<?= rawurlencode($catForLink) ?>">
                      <input type="hidden" name="_csrf" value="<?= htmlspecialchars($_SESSION['_csrf'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
                      <input type="hidden" name="_action" value="feature_toggle">
                      <input type="hidden" name="id" value="<?= $idForLink ?>">
                      <input type="hidden" name="to_on" value="<?= $isPicked ? 0 : 1 ?>">
                      <button type="submit" class="btn">
                        <?php if ($isPicked): ?>
                          <img src="assets/star-solid-active.svg" alt="特集ON" title="特集ON">
                        <?php else: ?>
                          <img src="assets/star-solid.svg" alt="特集OFF" title="特集OFF">
                        <?php endif; ?>
                      </button>
                    </form>
                  </div>
                <?php endif; ?>
              </td>
              <?php endif; ?>
              <td class="active"><?= ((int)($r['active'] ?? 1) === 1) ? '公開' : '非公開' ?></td>
              <td class="date"><?= $dateDisp ?></td>
              <td class="date"><?= $updatedDisp ?></td>
              <td class="btn-table">
                <div class="btns">
                  <form method="post" action="./items.php?category=<?= rawurlencode($catForLink) ?>">
                    <input type="hidden" name="_csrf" value="<?= htmlspecialchars($_SESSION['_csrf'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
                    <input type="hidden" name="_action" value="toggle">
                    <input type="hidden" name="id" value="<?= $idForLink ?>">
                    <?php $isActive = (int)($r['active'] ?? 1) === 1; ?>
                    <?php if ($isActive): ?>
                      <input type="hidden" name="to_active" value="0">
                      <button type="submit" class="btn" title="公開">
                        <img src="assets/lock-open-solid.svg" alt="公開" title="公開">
                      </button>
                    <?php else: ?>
                      <input type="hidden" name="to_active" value="1">
                      <button type="submit" class="btn" title="非公開">
                        <img src="assets/lock-solid.svg" alt="非公開" title="非公開">
                      </button>
                    <?php endif; ?>
                  </form>
                  <a class="btn" href="./regist.php?category=<?= rawurlencode($catForLink) ?>&id=<?= $idForLink ?>&mode=copy">
                    <img src="assets/copy-solid.svg" alt="複製" title="複製">
                  </a>
                  <form method="post" action="./items.php?category=<?= rawurlencode($catForLink) ?>" onsubmit="return confirm('このデータを削除します。よろしいですか？');">
                    <input type="hidden" name="_csrf" value="<?= htmlspecialchars($_SESSION['_csrf'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
                    <input type="hidden" name="_action" value="delete">
                    <input type="hidden" name="id" value="<?= $idForLink ?>">
                    <button type="submit" class="btn danger"><img src="assets/trash-can-solid.svg" alt="削除" title="削除"></button>
                  </form>
                </div>
              </td>
            </tr>
          <?php endforeach; ?>
        <?php endif; ?>
      </tbody>
      
      <?php
      // 新規作成フォームに一覧用ループ変数 $r が流入しないようクリア
      unset($r);
      ?>

    </table>
      <button type="submit" class="mb1rem" form="bulk-form" onclick="return confirm('選択したデータを削除します。よろしいですか？')">選択を削除</button>

  </div>

  <?php
    // ページャ（番号リンク式）
    $qsBase = './items.php?category=' . rawurlencode($categorySlug)
            . '&sort=' . rawurlencode($sortKey)
            . '&dir='  . rawurlencode($dirRaw)
            . '&per='  . $per
            . '&q='    . rawurlencode($q)
            . '&id='   . (($idEq > 0) ? (string)$idEq : '');

    if ($totalPages > 1) {
        $window = 5; // 何ページ分表示するか（例：5）
        $half   = intdiv($window - 1, 2);

        $start = max(1, $page - $half);
        $end   = min($totalPages, $start + $window - 1);
        // 末尾寄りで不足が出た場合の補正
        $start = max(1, $end - $window + 1);
  ?>
  <div class="pager">
    <?php if ($page > 1): ?>
      <a href="<?= $qsBase . '&page=' . ($page - 1) ?>">&laquo; 前へ</a>
    <?php else: ?>
      <span>&laquo; 前へ</span>
    <?php endif; ?>

    <?php for ($i = $start; $i <= $end; $i++): ?>
      <?php if ($i === $page): ?>
        <span><?= (int)$i ?></span>
      <?php else: ?>
        <a href="<?= $qsBase . '&page=' . $i ?>"><?= (int)$i ?></a>
      <?php endif; ?>
    <?php endfor; ?>

    <?php if ($page < $totalPages): ?>
      <a href="<?= $qsBase . '&page=' . ($page + 1) ?>">次へ &raquo;</a>
    <?php else: ?>
      <span>次へ &raquo;</span>
    <?php endif; ?>
  </div>
  <?php } ?>

  <?php if ($categorySlug !== ''): ?>
  <div class="mb1rem">
    <a class="btn1" href="./regist.php?category=<?= rawurlencode($categorySlug) ?>&id=new">新規作成</a>
  </div>
  <?php endif; ?>

<script src="<?= h(asset_url('/admin/assets/admin.js', true)) ?>"></script>
</body>
</html>
