<?php
// app/Models/UserRepository.php
// Repozitář pro práci s uživateli – CRUD, vyhledávání podle jména, týmy trenéra.

namespace App\Models;

use App\Core\Database;
use App\Models\Entities\UserEntity;

/**
 * Poskytuje metody pro čtení a zápis uživatelů do tabulky uzivatele.
 * Dědí základní find/findAll/delete z BaseRepository.
 */
class UserRepository extends BaseRepository
{
    public function __construct(Database $db)
    {
        parent::__construct($db, 'uzivatele', UserEntity::class);
    }

    /** Najde uživatele podle uživatelského jména; vrátí null pokud neexistuje. */
    public function findByUsername(string $username): ?UserEntity
    {
        $stmt = $this->pdo->prepare(
            "SELECT * FROM uzivatele WHERE uzivatelske_jmeno = :u LIMIT 1"
        );
        $stmt->execute(['u' => $username]);
        $row = $stmt->fetch();

        return $row ? $this->mapRowToEntity($row) : null;
    }

    /**
     * Vytvoří nového uživatele; pokud je sportovec a je zadán tym_id, přidá ho do týmu jako hráče.
     * Vrátí ID nově vytvořeného uživatele.
     */
    public function create(array $data, ?int $createdBy = null): int
    {
        $stmt = $this->pdo->prepare(
            "INSERT INTO uzivatele (uzivatelske_jmeno, jmeno, prijmeni, heslo, role, vytvoril_uzivatel_id)
             VALUES (:uzivatelske_jmeno, :jmeno, :prijmeni, :heslo, :role, :vytvoril_uzivatel_id)"
        );

        $stmt->execute([
            'uzivatelske_jmeno' => $data['uzivatelske_jmeno'],
            'jmeno' => $data['jmeno'],
            'prijmeni' => $data['prijmeni'],
            'heslo' => $data['heslo'],
            'role' => $data['role'] ?? 'sportovec',
            'vytvoril_uzivatel_id' => $createdBy
        ]);

        $userId = (int)$this->pdo->lastInsertId();

        // pokud je sportovec a zadáný tým, přidá ho do týmu jako hráče
        if (($data['role'] ?? 'sportovec') === 'sportovec' && !empty($data['tym_id'])) {
            $stmtTeam = $this->pdo->prepare(
                "INSERT INTO clenove_tymu (uzivatel_id, tym_id, role_v_tymu)
                 VALUES (:uzivatel_id, :tym_id, 'hrac')"
            );
            $stmtTeam->execute([
                'uzivatel_id' => $userId,
                'tym_id' => (int)$data['tym_id']
            ]);
        }

        return $userId;
    }

    /** Aktualizuje povolená pole uživatele (jméno, heslo, role). Ostatní klíče ignoruje. */
    public function update(int $id, array $data): bool
    {
        $povolenaPoleDat = ['uzivatelske_jmeno', 'jmeno', 'prijmeni', 'heslo', 'role'];
        
        $data = array_intersect_key($data, array_flip($povolenaPoleDat));
        
        if (empty($data)) {
            return true;
        }
        
        $set = implode(', ', array_map(fn($f) => "$f = :$f", array_keys($data)));
        $sql = "UPDATE uzivatele SET $set WHERE id = :id";
        
        $data['id'] = $id;
        
        return $this->pdo->prepare($sql)->execute($data);
    }

    /** Vrátí týmy, ve kterých má daný uživatel roli trenéra. */
    public function getTeamsForCoach(int $coachId): array
    {
        $stmt = $this->pdo->prepare(
            "SELECT DISTINCT t.id, t.nazev FROM tymy t
             JOIN clenove_tymu ct ON t.id = ct.tym_id
             WHERE ct.uzivatel_id = :uzivatel_id AND ct.role_v_tymu = 'trener'"
        );
        $stmt->execute(['uzivatel_id' => $coachId]);
        return $stmt->fetchAll();
    }

    /** Vrátí všechny týmy (id + nazev) seřazené abecedně – pro admin formuláře. */
    public function getAllTeams(): array
    {
        $stmt = $this->pdo->query("SELECT id, nazev FROM tymy ORDER BY nazev");
        return $stmt->fetchAll();
    }

    /**
     * Vrátí uživatele vytvořené daným trenérem, kteří nejsou v týmu (je-li teamId zadán)
     */
    public function getCreatedByUser(int $creatorId, ?int $teamId = null): array
    {
        if ($teamId === null) {
            // Vrátí všechny uživatele vytvořené daným trenérem
            $stmt = $this->pdo->prepare(
                "SELECT id, uzivatelske_jmeno, jmeno, prijmeni, role, vytvoril_uzivatel_id, datum_registrace 
                 FROM uzivatele 
                 WHERE vytvoril_uzivatel_id = :creator_id
                 ORDER BY jmeno ASC"
            );
            $stmt->execute(['creator_id' => $creatorId]);
        } else {
            // Vrátí uživatele vytvořené daným trenérem, kteří nejsou v daném týmu
            $stmt = $this->pdo->prepare(
                "SELECT id, uzivatelske_jmeno, jmeno, prijmeni, role, vytvoril_uzivatel_id, datum_registrace 
                 FROM uzivatele 
                 WHERE vytvoril_uzivatel_id = :creator_id
                 AND id NOT IN (
                     SELECT uzivatel_id FROM clenove_tymu WHERE tym_id = :team_id
                 )
                 ORDER BY jmeno ASC"
            );
            $stmt->execute(['creator_id' => $creatorId, 'team_id' => $teamId]);
        }
        return $stmt->fetchAll();
    }

    /**
     * Vrátí počet uživatelů vytvořených daným trenérem
     */
    public function getCountCreatedByUser(int $creatorId): int
    {
        $stmt = $this->pdo->prepare(
            "SELECT COUNT(*) as cnt FROM uzivatele WHERE vytvoril_uzivatel_id = :creator_id"
        );
        $stmt->execute(['creator_id' => $creatorId]);
        $result = $stmt->fetch(\PDO::FETCH_ASSOC);
        return (int)($result['cnt'] ?? 0);
    }

}