<?php

class PersonalHostGroupsModel extends BaseHostGroupsModel
{
    protected $table = 'personal_host_groups';
    public static $type = 'personal';

    protected string $defaultSortColumn = 'id';
    protected string $defaultSortDirection = 'ASC';

    public function get(int $id, bool $updateHostCountCache = true): array|bool
    {
        $stmt = $this->dbConnection->prepare("SELECT *, '" . static::$type . "' as type FROM {$this->table} WHERE owner = ? and id = ?");
        $stmt->execute([$this->username, $id]);
        $group = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$group) {
            return false;
        }

        if (isset($group['filter'])) {
            $group['filter'] = json_decode($group['filter'], true);
        }

        if ($updateHostCountCache) {
            // update a group hosts count when a single group request performed
            self::updateHostCountCachedValue($group, $this->username, $this->cfdbConnection);
        }

        return $group;
    }

    public function create(HostGroupEntity $groupEntity): bool|string
    {
        $sql = "INSERT INTO {$this->table} 
                (owner, name, description, filter, filter_sql) 
                VALUES (:owner, :name, :description, :filter, :filter_sql)";

        $this->dbConnection->prepare($sql)->execute($groupEntity->toArray());
        return $this->dbConnection->lastInsertId();
    }

    public function update(int $id, HostGroupEntity $groupEntity): bool
    {
        $set = [];
        $data = $groupEntity->changedItemsToArray();
        unset($data['owner']); // owner cannot be changed

        if (sizeof($data) === 0) {
            return true;
        }

        foreach ($data as $key => $value) {
            $set[] = "$key = :$key";
        }
        $data['id'] = $id;
        $sql = "UPDATE {$this->table} SET " . implode(', ', $set) . " WHERE id = :id";
        return $this->dbConnection->prepare($sql)->execute($data);
    }

    public function delete(int $id)
    {
        return $this
            ->dbConnection
            ->prepare("DELETE FROM {$this->table} WHERE owner = ? and id = ?")
            ->execute([$this->username, $id]);
    }

    public function makeShared(
        $id,
        SharedHostGroupEntity $sharedHostGroupsEntity,
        SharedHostGroupsModel $sharedHostGroupsModel
    ) {

        if (!$sharedHostGroupsModel->isNameUnique($sharedHostGroupsEntity->getName())) {
            throw new InvalidArgumentException('Shared group with the same name already exists.');
        }

        $this->dbConnection->beginTransaction();
        try {
            $sharedGroupId = $sharedHostGroupsModel->create($sharedHostGroupsEntity);
            $this->delete($id);
        } catch (Exception $exception) {
            $this->dbConnection->rollBack();
            throw $exception;
        }
        $this->dbConnection->commit();
        return $sharedGroupId;
    }
}
