<?php

declare(strict_types=1);

namespace OCA\Mitgliederverwaltung\Db;

use OCP\AppFramework\Db\QBMapper;
use OCP\DB\Exception;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;

/**
 * Mapper for the oc_mv_inventory_item_categories join table.
 *
 * Part of Issue #165 (Inventory Tracking).
 *
 * @extends QBMapper<InventoryItemCategory>
 */
class InventoryItemCategoryMapper extends QBMapper {

    public function __construct(IDBConnection $db) {
        parent::__construct($db, 'mv_inventory_item_categories', InventoryItemCategory::class);
    }

    /**
     * Find all categories linked to a given item.
     *
     * @return InventoryItemCategory[]
     * @throws Exception
     */
    public function findByItemId(int $itemId): array {
        $qb = $this->db->getQueryBuilder();
        $qb->select('*')
            ->from($this->getTableName())
            ->where($qb->expr()->eq('item_id', $qb->createNamedParameter($itemId, IQueryBuilder::PARAM_INT)));

        return $this->findEntities($qb);
    }

    /**
     * Attach a category to an item.
     *
     * @throws Exception
     */
    public function attach(int $itemId, int $categoryId): void {
        $qb = $this->db->getQueryBuilder();
        $qb->insert($this->getTableName())
            ->values([
                'item_id' => $qb->createNamedParameter($itemId, IQueryBuilder::PARAM_INT),
                'category_id' => $qb->createNamedParameter($categoryId, IQueryBuilder::PARAM_INT),
            ]);
        $qb->executeStatement();
    }

    /**
     * Detach a category from an item.
     *
     * @throws Exception
     */
    public function detach(int $itemId, int $categoryId): void {
        $qb = $this->db->getQueryBuilder();
        $qb->delete($this->getTableName())
            ->where($qb->expr()->eq('item_id', $qb->createNamedParameter($itemId, IQueryBuilder::PARAM_INT)))
            ->andWhere($qb->expr()->eq('category_id', $qb->createNamedParameter($categoryId, IQueryBuilder::PARAM_INT)));
        $qb->executeStatement();
    }
}
