<?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_lager_teilnehmer table.
 *
 * Part of Issue #54.
 *
 * @extends QBMapper<LagerTeilnehmer>
 */
class LagerTeilnehmerMapper extends QBMapper {

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

    /**
     * Find all participants across all camps.
     *
     * @return LagerTeilnehmer[]
     * @throws Exception
     */
    public function findAll(): array {
        $qb = $this->db->getQueryBuilder();
        $qb->select('*')
            ->from($this->getTableName());
        return $this->findEntities($qb);
    }

    /**
     * Find all participants for a camp.
     *
     * @return LagerTeilnehmer[]
     * @throws Exception
     */
    public function findByLagerId(int $lagerId): array {
        $qb = $this->db->getQueryBuilder();
        $qb->select('*')
            ->from($this->getTableName())
            ->where($qb->expr()->eq('lager_id', $qb->createNamedParameter($lagerId, IQueryBuilder::PARAM_INT)));
        return $this->findEntities($qb);
    }

    /**
     * Find all camps for a member (camp history).
     *
     * @return LagerTeilnehmer[]
     * @throws Exception
     */
    public function findByMemberId(int $memberId): array {
        $qb = $this->db->getQueryBuilder();
        $qb->select('*')
            ->from($this->getTableName())
            ->where($qb->expr()->eq('member_id', $qb->createNamedParameter($memberId, IQueryBuilder::PARAM_INT)));
        return $this->findEntities($qb);
    }

    /**
     * Add a participant to a camp.
     *
     * @throws Exception
     */
    public function addParticipant(int $lagerId, int $memberId, string $rolle = 'Teilnehmer'): void {
        $qb = $this->db->getQueryBuilder();
        $qb->insert($this->getTableName())
            ->values([
                'lager_id' => $qb->createNamedParameter($lagerId, IQueryBuilder::PARAM_INT),
                'member_id' => $qb->createNamedParameter($memberId, IQueryBuilder::PARAM_INT),
                'rolle' => $qb->createNamedParameter($rolle),
            ]);
        $qb->executeStatement();
    }

    /**
     * Remove a participant from a camp.
     *
     * @throws Exception
     */
    public function removeParticipant(int $lagerId, int $memberId): void {
        $qb = $this->db->getQueryBuilder();
        $qb->delete($this->getTableName())
            ->where($qb->expr()->eq('lager_id', $qb->createNamedParameter($lagerId, IQueryBuilder::PARAM_INT)))
            ->andWhere($qb->expr()->eq('member_id', $qb->createNamedParameter($memberId, IQueryBuilder::PARAM_INT)));
        $qb->executeStatement();
    }

    /**
     * Delete all participants for a camp.
     *
     * @throws Exception
     */
    public function deleteByLagerId(int $lagerId): void {
        $qb = $this->db->getQueryBuilder();
        $qb->delete($this->getTableName())
            ->where($qb->expr()->eq('lager_id', $qb->createNamedParameter($lagerId, IQueryBuilder::PARAM_INT)));
        $qb->executeStatement();
    }
}
