<?php
// app/Controllers/UserController.php
// Controller pro správu uživatelů – výpis, přidání, editace, smazání a detail profilu.

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Auth;
use App\Core\Database;
use App\Models\UserRepository;
use App\Models\TeamRepository;
use App\Models\DochazkaRepository;
use App\Models\StatisticsRepository;

/**
 * Spravuje uživatelské účty.
 * Admin vidí a spravuje všechny; trenér jen uživatele, které sám vytvořil;
 * sportovec vidí jen vlastní profil.
 */
class UserController extends Controller
{
    private UserRepository $users;

    public function __construct(Database $db)
    {
        parent::__construct($db);
        Auth::requireLogin();
        $this->users = new UserRepository($db);
    }

    /** Vypíše seznam uživatelů dle oprávnění přihlášeného uživatele. */
    public function index()
    {
        $user = Auth::user();

        if ($user['role'] === 'admin') {
            // Načti všechny uživatele včetně info o tvůrci
            $pdo = $this->users->getPdo();
            $stmt = $pdo->prepare(
                "SELECT u.id, u.uzivatelske_jmeno, u.jmeno, u.prijmeni, u.role, u.datum_registrace, u.vytvoril_uzivatel_id,
                        creator.uzivatelske_jmeno as vytvoril_uzivatelske_jmeno
                 FROM uzivatele u
                 LEFT JOIN uzivatele creator ON u.vytvoril_uzivatel_id = creator.id
                 ORDER BY u.jmeno ASC"
            );
            $stmt->execute();
            $users = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        } elseif ($user['role'] === 'trener') {
            // trenér vidí jen uživatele, které vytvořil
            $createdUsers = $this->users->getCreatedByUser($user['id'], null);
            // Odfiltruj sebe sama
            $users = array_filter($createdUsers, fn($u) => $u['id'] !== $user['id']);
        } else {
            $this->abort(403, 'Nemáte oprávnění');
        }

        $this->view->render('users/index', [
            'users' => $users,
            'isAdmin' => $user['role'] === 'admin'
        ]);
    }

    /** GET: zobrazí formulář pro vytvoření uživatele. POST: uloží nového uživatele. */
    public function pridat()
    {
        $user = Auth::user();

        // jen admin a trenéři mohou vytvářet uživatele
        if (!in_array($user['role'], ['admin', 'trener'])) {
            $this->abort(403, 'Nemáte oprávnění');
        }

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $data = $this->validate($_POST, $user['role']);
            $this->users->create($data, $user['id']);
            Auth::setFlash('success', 'Uživatel byl úspěšně vytvořen!');
            $this->redirect(BASE_URL . '/user/index');
        }

        // načte týmy
        if ($user['role'] === 'admin') {
            $teams = $this->users->getAllTeams();
        } else {
            // trenér vidí jen svoje týmy
            $teams = $this->users->getTeamsForCoach($user['id']);
        }

        $this->view->render('users/create', [
            'userRole' => $user['role'],
            'teams' => $teams,
            'allowSportovecOnly' => $user['role'] === 'trener'
        ]);
    }

    /**
     * GET: zobrazí formulář pro editaci uživatele.
     * POST: uloží změny. Admin může editovat vše; trenér jen své sportovce; každý svůj profil.
     */
    public function edit()
    {
        $id = (int)($_GET['id'] ?? 0);
        $editUser = $this->users->find($id);
        $currentUser = Auth::user();

        if (!$editUser) {
            $this->abort(404, 'Uživatel nenalezen');
        }

        // admin může editovat všechny, trenér jen své sportovce, každý může editovat vlastní profil
        $isSelf = $id === (int)$currentUser['id'];
        if (!$isSelf && $currentUser['role'] !== 'admin') {
            if ($currentUser['role'] === 'trener') {
                $pdo = $this->users->getPdo();
                $stmt = $pdo->prepare(
                    "SELECT COUNT(*) as cnt FROM clenove_tymu ct
                     JOIN (SELECT id FROM tymy WHERE EXISTS (
                        SELECT 1 FROM clenove_tymu ct2 WHERE ct2.tym_id = tymy.id AND ct2.uzivatel_id = :coach_id AND ct2.role_v_tymu = 'trener'
                     )) t ON t.id = ct.tym_id
                     WHERE ct.uzivatel_id = :user_id"
                );
                $stmt->execute([':coach_id' => $currentUser['id'], ':user_id' => $id]);
                $result = $stmt->fetch(\PDO::FETCH_ASSOC);
                if ((int)($result['cnt'] ?? 0) === 0) {
                    $this->abort(403, 'Nemáte oprávnění');
                }
            } else {
                $this->abort(403, 'Nemáte oprávnění');
            }
        }

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $data = $this->validate($_POST, $currentUser['role'], true);
            $this->users->update($id, $data);
            Auth::setFlash('success', 'Uživatel byl úspěšně aktualizován!');
            $this->redirect(BASE_URL . '/user/show?id=' . $id);
        }

        $userArray = is_array($editUser) ? $editUser : $editUser->toArray();

        $this->view->render('users/edit', ['user' => $userArray, 'userRole' => $currentUser['role'], 'isSelf' => $isSelf]);
    }

    /**
     * Smaže uživatele. Nikdo nemůže smazat sám sebe.
     * Admin maže kohokoli; trenér jen sportovce, které vytvořil.
     */
    public function delete()
    {
        $id = (int)($_GET['id'] ?? 0);
        $editUser = $this->users->find($id);
        $currentUser = Auth::user();

        if (!$editUser) {
            $this->abort(404, 'Uživatel nenalezen');
        }

        // nikdo nemůže smazat vlastní účet
        if ($id === (int)$currentUser['id']) {
            Auth::setFlash('error', 'Nemůžete smazat vlastní účet.');
            $this->redirect(BASE_URL . '/user/show?id=' . $id);
        }

        $editUserArray = is_array($editUser) ? $editUser : $editUser->toArray();

        if ($currentUser['role'] === 'admin') {
            // admin může smazat kohokoliv kromě sebe (ošetřeno výše)
        } elseif ($currentUser['role'] === 'trener') {
            // trenér může smazat jen sportovce, které sám vytvořil
            if (
                $editUserArray['role'] !== 'sportovec' ||
                (int)($editUserArray['vytvoril_uzivatel_id'] ?? 0) !== (int)$currentUser['id']
            ) {
                $this->abort(403, 'Nemáte oprávnění');
            }
        } else {
            $this->abort(403, 'Nemáte oprávnění');
        }

        $this->users->delete($id);
        Auth::setFlash('success', 'Uživatel byl úspěšně smazán!');
        $this->redirect(BASE_URL . '/user/index');
    }

    /** Zobrazí detail profilu uživatele včetně týmů, docházky a statistik. */
    public function show()
    {
        $id = (int)($_GET['id'] ?? 0);
        $user = $this->users->find($id);

        if (!$user) {
            $this->abort(404, 'Uživatel nenalezen');
        }

        $userArray = is_array($user) ? $user : $user->toArray();
        $currentUser = Auth::user();
        $currentUserId = (int)$currentUser['id'];

        $isSelf = $currentUserId === (int)$userArray['id'];

        if ($currentUser['role'] !== 'admin') {
            if ($currentUser['role'] === 'trener') {
                $canView = $isSelf || (int)($userArray['vytvoril_uzivatel_id'] ?? 0) === $currentUserId;
            } else {
                // sportovec vidí jen sebe
                $canView = $isSelf;
            }
            if (!$canView) {
                $this->abort(403, 'Nemáte oprávnění zobrazit tohoto uživatele');
            }
        }

        if ($currentUser['role'] === 'admin') {
            $canDelete = !$isSelf;
        } elseif ($currentUser['role'] === 'trener') {
            $canDelete = !$isSelf
                && $userArray['role'] === 'sportovec'
                && (int)($userArray['vytvoril_uzivatel_id'] ?? 0) === $currentUserId;
        } else {
            $canDelete = false;
        }

        $userId = (int)$userArray['id'];
        $teams        = (new TeamRepository($this->db))->getTeamsForUserWithRole($userId);
        $dochazka     = (new DochazkaRepository($this->db))->getAttendanceSummaryForUser($userId);
        $statistiky   = (new StatisticsRepository($this->db))->getStatsForUser($userId);

        $this->view->render('users/show', [
            'user' => $userArray,
            'currentUserRole' => $currentUser['role'],
            'currentUserId' => $currentUserId,
            'canDelete' => $canDelete,
            'teams' => $teams,
            'dochazka' => $dochazka,
            'statistiky' => $statistiky,
        ]);
    }

    /**
     * Validuje a sanitizuje vstup z formuláře.
     * Při vytváření ($isEdit=false) je heslo povinné (min. 8 znaků).
     * Při editaci se heslo přepíše pouze pokud bylo vyplněno.
     * Role lze nastavit pouze admin; trenér vždy vytváří sportovce.
     */
    private function validate(array $input, string $userRole, bool $isEdit = false): array
    {
        $data = [
            'uzivatelske_jmeno' => trim($input['uzivatelske_jmeno'] ?? ''),
            'jmeno' => trim($input['jmeno'] ?? ''),
            'prijmeni' => trim($input['prijmeni'] ?? ''),
        ];

        // heslo je povinné při vytváření
        if (!$isEdit) {
            $password = trim($input['heslo'] ?? '');
            if (strlen($password) < 8) {
                $this->abort(400, 'Heslo musí mít alespoň 8 znaků');
            }
            $data['heslo'] = password_hash($password, PASSWORD_DEFAULT);
        } elseif (!empty($input['heslo'])) {
            $password = trim($input['heslo']);
            if (strlen($password) >= 8) {
                $data['heslo'] = password_hash($password, PASSWORD_DEFAULT);
            }
        }

        // admin může přiřadit roli, ostatní ne
        if ($userRole === 'admin') {
            $role = $input['role'] ?? 'sportovec';
            if (in_array($role, ['admin', 'trener', 'sportovec'])) {
                $data['role'] = $role;
            }
        } elseif (!$isEdit) {
            // trenér vytváří jen sportovce; při editaci se role nemění
            $data['role'] = 'sportovec';
        }

        // tým je povinný pro sportovce
        if (($data['role'] ?? 'sportovec') === 'sportovec' && !empty($input['tym_id'])) {
            $data['tym_id'] = (int)$input['tym_id'];
        }

        return $data;
    }
}
