<?php
class Model
{
    protected string $table = '';
    protected string $primaryKey = 'id';
    protected Database $db;

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

    public function find(int $id): ?array
    {
        return $this->db->fetchOne(
            "SELECT * FROM `{$this->table}` WHERE `{$this->primaryKey}` = ?",
            [$id]
        );
    }

    public function all(array $conditions = [], string $orderBy = 'id DESC', int $limit = 100): array
    {
        $where = '1=1';
        $params = [];
        foreach ($conditions as $col => $val) {
            $where .= " AND `{$col}` = ?";
            $params[] = $val;
        }
        return $this->db->fetchAll(
            "SELECT * FROM `{$this->table}` WHERE {$where} ORDER BY {$orderBy} LIMIT ?",
            array_merge($params, [$limit])
        );
    }

    public function create(array $data): int
    {
        return $this->db->insert($this->table, $data);
    }

    public function updateById(int $id, array $data): int
    {
        return $this->db->update($this->table, $data, "`{$this->primaryKey}` = ?", [$id]);
    }

    public function softDelete(int $id, int $userId): int
    {
        return $this->db->update($this->table, [
            'is_deleted' => 1,
            'deleted_at' => date('Y-m-d H:i:s'),
            'deleted_by' => $userId,
        ], "`{$this->primaryKey}` = ?", [$id]);
    }

    public function exists(int $id): bool
    {
        return (bool) $this->db->fetchColumn(
            "SELECT COUNT(*) FROM `{$this->table}` WHERE `{$this->primaryKey}` = ?",
            [$id]
        );
    }

    public function count(array $conditions = []): int
    {
        $where = '1=1';
        $params = [];
        foreach ($conditions as $col => $val) {
            $where .= " AND `{$col}` = ?";
            $params[] = $val;
        }
        return (int) $this->db->fetchColumn(
            "SELECT COUNT(*) FROM `{$this->table}` WHERE {$where}",
            $params
        );
    }
}