<?php
/**
 * Kontroler użytkowników (admin/reseller)
 */

require_once __DIR__ . '/BaseController.php';

class UserController extends BaseController
{
    private User $userModel;
    private AuditLog $auditLog;

    public function __construct()
    {
        parent::__construct();
        $this->userModel = new User();
        $this->auditLog = new AuditLog();
    }

    /**
     * Lista użytkowników
     */
    public function index(): void
    {
        // Tylko admin i reseller mają dostęp
        if (!$this->auth->isManager()) {
            $this->redirect('/', 'danger', 'Brak dostępu.');
            return;
        }

        $search = get('search');
        $page = max(1, (int)get('page', 1));
        
        // Pobierz użytkowników widocznych dla aktualnego managera
        $total = $this->userModel->countVisible($this->currentUser, $search);
        $pagination = paginate($total, ITEMS_PER_PAGE, $page);
        
        $users = $this->userModel->getVisibleUsers($this->currentUser, ITEMS_PER_PAGE, $pagination['offset'], $search);

        // Dla resellera - pobierz wykorzystanie limitów
        $resellerUsage = null;
        $availableLimits = null;
        if ($this->auth->isReseller()) {
            $resellerUsage = $this->userModel->getResellerUsage($this->currentUser['id']);
            $availableLimits = $this->userModel->getResellerAvailableLimits($this->currentUser['id']);
        }

        // Dla admina - pobierz listę resellerów do filtrowania
        $resellers = [];
        if ($this->auth->isAdmin()) {
            $resellers = $this->userModel->getResellers();
        }

        $this->render('users/list.tpl', [
            'pageTitle' => 'Użytkownicy',
            'users' => $users,
            'pagination' => $pagination,
            'search' => $search,
            'resellers' => $resellers,
            'resellerUsage' => $resellerUsage,
            'availableLimits' => $availableLimits
        ]);
    }

    /**
     * Dodaj użytkownika
     */
    public function add(): void
    {
        // Tylko admin i reseller mają dostęp
        if (!$this->auth->isManager()) {
            $this->redirect('/', 'danger', 'Brak dostępu.');
            return;
        }

        // Dla resellera - pobierz dostępne limity
        $availableLimits = null;
        if ($this->auth->isReseller()) {
            $availableLimits = $this->userModel->getResellerAvailableLimits($this->currentUser['id']);
            
            // Sprawdź czy reseller może dodać kolejnego użytkownika
            if ($availableLimits['users'] <= 0) {
                $this->redirect('users', 'danger', 'Osiągnięto limit użytkowników.');
                return;
            }
        }

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            if (!$this->verifyCsrf()) {
                return;
            }

            $role = post('role', 'user');
            
            // Reseller może tworzyć tylko userów
            if ($this->auth->isReseller()) {
                $role = 'user';
            }

            $data = [
                'username' => post('new_account_login'),
                'password' => post('new_account_secret'),
                'role' => $role,
                'device_limit' => post('device_limit', getSetting('default_device_limit', 3)),
                'playlist_limit' => post('playlist_limit', getSetting('default_playlist_limit', 100))
            ];

            // Admin może przypisać parent_id (resellera)
            if ($this->auth->isAdmin()) {
                $parentId = post('parent_id');
                if ($parentId) {
                    $data['parent_id'] = (int)$parentId;
                } else {
                    // Jeśli nie wybrano resellera, przypisz do admina
                    $data['parent_id'] = $this->currentUser['id'];
                }

                // Dla resellera - dodatkowe pola limitów
                if ($role === 'reseller') {
                    $data['max_users'] = post('max_users', 10);
                    $data['max_devices'] = post('max_devices', 50);
                    $data['max_playlists'] = post('max_playlists', 200);
                }
            }

            $result = $this->userModel->create($data, $this->currentUser['id']);

            // Audit log
            if ($result['success'] && isset($result['id'])) {
                $this->auditLog->log(
                    AuditLog::ENTITY_USER,
                    $result['id'],
                    AuditLog::ACTION_CREATE,
                    null,
                    ['username' => $data['username'], 'role' => $data['role']]
                );
                
                // Dodaj notatkę jeśli podano
                $initialNote = trim(post('initial_note', ''));
                if ($initialNote) {
                    $notesModel = new EntityNotes();
                    $notesModel->add('user', $result['id'], $this->currentUser['id'], [
                        'title' => 'Uwagi przy tworzeniu',
                        'content' => $initialNote,
                        'color' => 'blue'
                    ]);
                }
            }

            if (isAjax()) {
                $this->json($result);
            } else {
                if ($result['success']) {
                    $this->redirect('users', 'success', 'Użytkownik został dodany.');
                } else {
                    $resellers = $this->auth->isAdmin() ? $this->userModel->getResellers() : [];
                    $this->render('users/form.tpl', [
                        'pageTitle' => 'Dodaj użytkownika',
                        'error' => $result['error'],
                        'data' => $data,
                        'isEdit' => false,
                        'resellers' => $resellers,
                        'availableLimits' => $availableLimits,
                        'passwordSettings' => getPasswordSettingsJson()
                    ]);
                }
            }
            return;
        }

        $resellers = $this->auth->isAdmin() ? $this->userModel->getResellers() : [];

        $this->render('users/form.tpl', [
            'pageTitle' => 'Dodaj użytkownika',
            'isEdit' => false,
            'data' => [
                'role' => 'user', 
                'device_limit' => getSetting('default_device_limit', 3), 
                'playlist_limit' => getSetting('default_playlist_limit', 100)
            ],
            'resellers' => $resellers,
            'availableLimits' => $availableLimits,
            'passwordSettings' => getPasswordSettingsJson()
        ]);
    }

    /**
     * Edytuj użytkownika
     */
    public function edit(): void
    {
        // Tylko admin i reseller mają dostęp
        if (!$this->auth->isManager()) {
            $this->redirect('/', 'danger', 'Brak dostępu.');
            return;
        }

        $id = (int)get('id');
        $user = $this->userModel->getById($id);

        if (!$user) {
            $this->redirect('users', 'danger', 'Użytkownik nie istnieje.');
            return;
        }

        // Sprawdź czy manager może edytować tego użytkownika
        if (!$this->auth->canManageUser($id)) {
            $this->redirect('users', 'danger', 'Brak dostępu do tego użytkownika.');
            return;
        }

        // Dla resellera - pobierz dostępne limity
        $availableLimits = null;
        if ($this->auth->isReseller()) {
            $availableLimits = $this->userModel->getResellerAvailableLimits($this->currentUser['id']);
            // Dodaj aktualne limity edytowanego użytkownika
            $availableLimits['devices'] += $user['device_limit'];
            $availableLimits['playlists'] += $user['playlist_limit'];
        }

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            if (!$this->verifyCsrf()) {
                return;
            }

            $data = [
                'username' => post('new_account_login'),
                'device_limit' => post('device_limit'),
                'playlist_limit' => post('playlist_limit'),
                'is_active' => post('is_active') !== null
            ];

            // Zmiana hasła - jeśli podano nowe
            $newPassword = trim(post('new_account_secret', ''));
            if ($newPassword) {
                $data['password'] = $newPassword;
            }

            // Tylko admin może zmieniać rolę i parent_id
            if ($this->auth->isAdmin()) {
                $data['role'] = post('role');
                $data['parent_id'] = post('parent_id') ?: null;

                // Dla resellera - limity
                if (post('role') === 'reseller') {
                    $data['max_users'] = post('max_users', 10);
                    $data['max_devices'] = post('max_devices', 50);
                    $data['max_playlists'] = post('max_playlists', 200);
                }
            }

            // Reseller - sprawdź limity
            if ($this->auth->isReseller()) {
                $limitCheck = $this->userModel->checkResellerLimits(
                    $this->currentUser['id'],
                    (int)$data['device_limit'],
                    (int)$data['playlist_limit'],
                    $id
                );
                if (!$limitCheck['success']) {
                    $resellers = $this->auth->isAdmin() ? $this->userModel->getResellers() : [];
                    $this->render('users/form.tpl', [
                        'pageTitle' => 'Edytuj użytkownika',
                        'error' => $limitCheck['error'],
                        'data' => array_merge($user, $data),
                        'isEdit' => true,
                        'resellers' => $resellers,
                        'availableLimits' => $availableLimits,
                        'passwordSettings' => getPasswordSettingsJson()
                    ]);
                    return;
                }
            }

            $result = $this->userModel->update($id, $data, $this->currentUser['id']);

            // Audit log
            if ($result['success']) {
                $this->auditLog->log(
                    AuditLog::ENTITY_USER,
                    $id,
                    AuditLog::ACTION_UPDATE,
                    $user,
                    array_merge($user, $data)
                );
            }

            if (isAjax()) {
                $this->json($result);
            } else {
                if ($result['success']) {
                    $this->redirect('users', 'success', 'Użytkownik został zaktualizowany.');
                } else {
                    $resellers = $this->auth->isAdmin() ? $this->userModel->getResellers() : [];
                    $this->render('users/form.tpl', [
                        'pageTitle' => 'Edytuj użytkownika',
                        'error' => $result['error'],
                        'data' => array_merge($user, $data),
                        'isEdit' => true,
                        'resellers' => $resellers,
                        'availableLimits' => $availableLimits,
                        'passwordSettings' => getPasswordSettingsJson()
                    ]);
                }
            }
            return;
        }

        $resellers = $this->auth->isAdmin() ? $this->userModel->getResellers() : [];

        $this->render('users/form.tpl', [
            'pageTitle' => 'Edytuj użytkownika',
            'isEdit' => true,
            'data' => $user,
            'resellers' => $resellers,
            'availableLimits' => $availableLimits,
            'passwordSettings' => getPasswordSettingsJson()
        ]);
    }

    /**
     * Usuń użytkownika
     */
    public function delete(): void
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->redirect('users');
            return;
        }

        if (!$this->verifyCsrf()) {
            return;
        }

        // Tylko admin i reseller mają dostęp
        if (!$this->auth->isManager()) {
            $this->redirect('/', 'danger', 'Brak dostępu.');
            return;
        }

        $id = (int)post('id');
        
        // Nie pozwól usunąć samego siebie
        if ($id === $this->currentUser['id']) {
            if (isAjax()) {
                $this->json(['success' => false, 'error' => 'Nie możesz usunąć swojego konta.']);
            } else {
                $this->redirect('users', 'danger', 'Nie możesz usunąć swojego konta.');
            }
            return;
        }

        // Sprawdź czy manager może usunąć tego użytkownika
        if (!$this->auth->canManageUser($id)) {
            if (isAjax()) {
                $this->json(['success' => false, 'error' => 'Brak dostępu do tego użytkownika.']);
            } else {
                $this->redirect('users', 'danger', 'Brak dostępu do tego użytkownika.');
            }
            return;
        }

        // Reseller nie może usuwać innych resellerów ani adminów
        if ($this->auth->isReseller()) {
            $targetUser = $this->userModel->getById($id);
            if ($targetUser && $targetUser['role'] !== 'user') {
                if (isAjax()) {
                    $this->json(['success' => false, 'error' => 'Nie masz uprawnień do usunięcia tego użytkownika.']);
                } else {
                    $this->redirect('users', 'danger', 'Nie masz uprawnień do usunięcia tego użytkownika.');
                }
                return;
            }
        }

        // Pobierz dane przed usunięciem dla audit log
        $userToDelete = $this->userModel->getById($id);
        
        $result = $this->userModel->delete($id, $this->currentUser['id']);

        // Audit log
        if ($result['success'] && $userToDelete) {
            $this->auditLog->log(
                AuditLog::ENTITY_USER,
                $id,
                AuditLog::ACTION_DELETE,
                ['username' => $userToDelete['username'], 'role' => $userToDelete['role']],
                null
            );
        }

        if (isAjax()) {
            $this->json($result);
        } else {
            if ($result['success']) {
                $this->redirect('users', 'success', 'Użytkownik został usunięty.');
            } else {
                $this->redirect('users', 'danger', $result['error']);
            }
        }
    }

    /**
     * Resetuj hasło użytkownika
     */
    public function resetPassword(): void
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->redirect('users');
            return;
        }

        if (!$this->verifyCsrf()) {
            return;
        }

        // Tylko admin i reseller mają dostęp
        if (!$this->auth->isManager()) {
            $this->redirect('/', 'danger', 'Brak dostępu.');
            return;
        }

        $id = (int)post('id');
        $newPassword = post('new_password');

        // Sprawdź czy manager może zarządzać tym użytkownikiem
        if (!$this->auth->canManageUser($id)) {
            if (isAjax()) {
                $this->json(['success' => false, 'error' => 'Brak dostępu do tego użytkownika.']);
            } else {
                $this->redirect('users', 'danger', 'Brak dostępu do tego użytkownika.');
            }
            return;
        }

        if (empty($newPassword)) {
            if (isAjax()) {
                $this->json(['success' => false, 'error' => 'Hasło jest wymagane.']);
            } else {
                $this->redirect('users', 'danger', 'Hasło jest wymagane.');
            }
            return;
        }

        $result = $this->auth->resetPassword($id, $newPassword);

        // Audit log
        if ($result['success']) {
            $user = $this->userModel->getById($id);
            $this->auditLog->log(
                AuditLog::ENTITY_USER,
                $id,
                'password_reset',
                null,
                ['username' => $user['username'] ?? 'unknown']
            );
        }

        if (isAjax()) {
            $this->json($result);
        } else {
            if ($result['success']) {
                $this->redirect('users', 'success', 'Hasło zostało zresetowane.');
            } else {
                $this->redirect('users', 'danger', $result['error']);
            }
        }
    }
}
