<?php
/**
 * Zentrale DB‑Zugriffe für Tags mit Expiration‑Support
 * ---------------------------------------------------
 *
 * ▸ Vollständiges Error‑Handling
 * ▸ Sämtliche SQL‑Operationen werden mit ErrorLogger::logSqlSuccess() / logSqlError() protokolliert
 *   ⇒ Hierbei **immer** das reine SQL‑Statement (string) übergeben, *nicht* das PDOStatement‑Objekt!
 * ▸ Änderungen werden zusätzlich via logSettingChange() festgehalten
 */

class TagRepository
{
    /** @var PDO */
    private $db;

    public function __construct()
    {
        $this->db = Database::getInstance();
    }

    // ---------------------------------------------------------------------
    // 1) CREATE – neuen Tag anlegen
    // ---------------------------------------------------------------------
    public function create(string $name, ?string $expirationDate, int $userId): bool
    {
        $sql = 'INSERT INTO tags (name, expiration_date) VALUES (:name, :expiration_date)';

        try {
            $stmt = $this->db->prepare($sql);
            $stmt->bindValue(':name', $name);
            $stmt->bindValue(':expiration_date', $expirationDate ?: null, PDO::PARAM_STR);

            $ok = $stmt->execute();
            ErrorLogger::logSqlSuccess($sql);                 // ← nur der SQL‑String

            if ($ok) {
                logSettingChange($userId, 'create', 'tag', json_encode([
                    'name'            => $name,
                    'expiration_date' => $expirationDate
                ]));
            }

            return $ok;
        } catch (Throwable $e) {
            ErrorLogger::logSqlError('TagRepository create | SQL: ' . $sql . ' | error: ' . $e->getMessage());
            return false;
        }
    }

    // ---------------------------------------------------------------------
    // 2) UPDATE – bestehenden Tag ändern
    // ---------------------------------------------------------------------
    public function update(int $tagId, string $name, ?string $expirationDate, int $userId): bool
    {
        $sql = 'UPDATE tags
                SET name = :name,
                    expiration_date = :expiration_date
                WHERE id = :id';

        try {
            $stmt = $this->db->prepare($sql);
            $stmt->bindValue(':id',   $tagId, PDO::PARAM_INT);
            $stmt->bindValue(':name', $name);
            $stmt->bindValue(':expiration_date', $expirationDate ?: null, PDO::PARAM_STR);

            $ok = $stmt->execute();
            ErrorLogger::logSqlSuccess($sql);

            if ($ok) {
                logSettingChange($userId, 'update', 'tag', json_encode([
                    'id'              => $tagId,
                    'name'            => $name,
                    'expiration_date' => $expirationDate
                ]));
            }

            return $ok;
        } catch (Throwable $e) {
            ErrorLogger::logSqlError('TagRepository update | SQL: ' . $sql . ' | error: ' . $e->getMessage());
            return false;
        }
    }

    // ---------------------------------------------------------------------
    // 3) READ – alle Tags (optional ohne abgelaufene)
    // ---------------------------------------------------------------------
    public function all(bool $onlyValid = true): array
    {
        $sql = 'SELECT id, name, expiration_date FROM tags';
        if ($onlyValid) {
            $sql .= ' WHERE expiration_date IS NULL OR expiration_date >= CURDATE()';
        }
        $sql .= ' ORDER BY name ASC';

        try {
            $stmt = $this->db->query($sql);
            ErrorLogger::logSqlSuccess($sql);
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Throwable $e) {
            ErrorLogger::logSqlError('TagRepository all | SQL: ' . $sql . ' | error: ' . $e->getMessage());
            return [];
        }
    }
}
