<?php
declare(strict_types=1);

require_once __DIR__ . '/../db.php';

/**
 * LD-02 カテゴリ管理：モデル関数群
 * - このファイルが読み込まれたタイミングでテーブルを確実に用意
 */
db_migrate_categories();

/**
 * 一覧取得（作成日の新しい順）
 * @param bool $onlyActive true なら公開中のみ
 * @return array<int, array<string, mixed>>
 */
function tpcms_cat_all(bool $onlyActive = false): array {
    $pdo = db();
    if ($onlyActive) {
        $stmt = $pdo->prepare("SELECT * FROM categories WHERE is_active = 1 ORDER BY created_at DESC, id DESC");
        $stmt->execute();
    } else {
        $stmt = $pdo->query("SELECT * FROM categories ORDER BY created_at DESC, id DESC");
    }
    return $stmt->fetchAll();
}

/**
 * ID で1件取得
 * @return array<string, mixed>|null
 */
function tpcms_cat_find_by_id(int $id): ?array {
    $stmt = db()->prepare("SELECT * FROM categories WHERE id = :id LIMIT 1");
    $stmt->execute([':id' => $id]);
    $row = $stmt->fetch();
    return $row !== false ? $row : null;
}

/**
 * slug で1件取得
 * @return array<string, mixed>|null
 */
function tpcms_cat_find_by_slug(string $slug): ?array {
    $stmt = db()->prepare("SELECT * FROM categories WHERE slug = :slug LIMIT 1");
    $stmt->execute([':slug' => $slug]);
    $row = $stmt->fetch();
    return $row !== false ? $row : null;
}

/**
 * 新規作成
 * @return int 挿入されたID
 */
function tpcms_cat_insert(string $name, string $slug, bool $isActive = true): int {
    $name = trim($name);
    $slug = trim($slug);

    // slug の許可文字（英数・ハイフン・アンダースコア）
    if ($slug === '' || !preg_match('~^[A-Za-z0-9_-]+$~', $slug)) {
        throw new InvalidArgumentException('スラッグの形式が正しくありません（英数字・ハイフン・アンダースコアのみ）。');
    }
    if ($name === '') {
        throw new InvalidArgumentException('名前は必須です。');
    }

    $stmt = db()->prepare("
        INSERT INTO categories (name, slug, is_active, created_at, updated_at)
        VALUES (:name, :slug, :is_active, datetime('now'), NULL)
    ");
    $stmt->execute([
        ':name'      => $name,
        ':slug'      => $slug,
        ':is_active' => $isActive ? 1 : 0,
    ]);
    return (int)db()->lastInsertId();
}

/**
 * 更新
 */
function tpcms_cat_update(int $id, string $name, string $slug, bool $isActive): void {
    $name = trim($name);
    $slug = trim($slug);
    if ($slug === '' || !preg_match('~^[A-Za-z0-9_-]+$~', $slug)) {
        throw new InvalidArgumentException('スラッグの形式が正しくありません（英数字・ハイフン・アンダースコアのみ）。');
    }
    if ($name === '') {
        throw new InvalidArgumentException('名前は必須です。');
    }

    $stmt = db()->prepare("
        UPDATE categories
           SET name = :name,
               slug = :slug,
               is_active = :is_active,
               updated_at = datetime('now')
         WHERE id = :id
    ");
    $stmt->execute([
        ':id'        => $id,
        ':name'      => $name,
        ':slug'      => $slug,
        ':is_active' => $isActive ? 1 : 0,
    ]);
}

/**
 * 公開フラグの切り替え
 */
function tpcms_cat_set_active(int $id, bool $isActive): void {
    $stmt = db()->prepare("
        UPDATE categories SET is_active = :is_active, updated_at = datetime('now')
         WHERE id = :id
    ");
    $stmt->execute([
        ':id'        => $id,
        ':is_active' => $isActive ? 1 : 0,
    ]);
}

/**
 * 削除
 * - 参照整合性は今後の「記事テーブル」導入時に外部キーで制御予定
 */
function tpcms_cat_delete(int $id): void {
    $stmt = db()->prepare("DELETE FROM categories WHERE id = :id");
    $stmt->execute([':id' => $id]);
}
