<?php

class Account extends BaseEntity {

    protected $db_name = 'accounts';
    protected $db_name_session = 'accounts_session';

    // Переменные свойств объекта

    public $id_department;
    public $name;
    public $username;
    public $password;
    public $avatar_url;
    public $telegram;

    // Валидация данных при создании аккаунта
    protected function validate() {
        static::$error_message = [];

        // === ИМЯ ===
        if (!$this->name) {
            $this->addError('name', 'Имя не может быть пустым');
        } elseif (mb_strlen($this->name) < 2) {
            $this->addError('name', 'Имя слишком короткое');
        } elseif (mb_strlen($this->name) > 50) {
            $this->addError('name', 'Имя слишком длинное');
        } elseif (!preg_match('/^[\p{L}\s\-]+$/u', $this->name)) {
            // Только буквы (любого языка), пробелы и дефис
            $this->addError('name', 'Имя может содержать только буквы');
        }

        // === ЛОГИН ===
        if (!$this->username) {
            $this->addError('username', 'Логин не может быть пустым');
        } elseif (strlen($this->username) < 3) {
            $this->addError('username', 'Логин минимум 3 символа');
        } elseif (strlen($this->username) > 32) {
            $this->addError('username', 'Логин максимум 32 символа');
        } elseif (!preg_match('/^[a-zA-Z][a-zA-Z0-9_]*$/', $this->username)) {
            // Начинается с буквы, далее a-z, 0-9, _
            $this->addError('username', 'Логин: латиница, цифры и _ (начинается с буквы)');
        } elseif (Database::get($this->db_name, ['id'], ['username' => $this->username])) {
            $this->addError('username', 'Этот логин уже занят');
        }

        // === ПАРОЛЬ ===
        if (!$this->password) {
            $this->addError('password', 'Пароль не может быть пустым');
        } elseif (strlen($this->password) < 6) {
            $this->addError('password', 'Пароль минимум 6 символов');
        } elseif (strlen($this->password) > 100) {
            $this->addError('password', 'Пароль слишком длинный');
        }

        return $this->getErrors();
    }

    // Очистка данных перед сохранением
    protected function sanitize() {
        // Имя: убираем лишние пробелы
        $this->name = trim(preg_replace('/\s+/', ' ', $this->name));
        
        // Логин: только допустимые символы (регистр сохраняется)
        $this->username = preg_replace('/[^a-zA-Z0-9_]/', '', $this->username);
        
        // Telegram: убираем @, только допустимые символы
        if ($this->telegram) {
            $this->telegram = str_replace('@', '', $this->telegram);
            $this->telegram = preg_replace('/[^a-zA-Z0-9_]/', '', $this->telegram);
            $this->telegram = strtolower($this->telegram);
            $this->telegram = $this->telegram ?: null;
        }
    }

    // Создание нового аккаунта
    public function create() {
        
        // Очищаем данные
        $this->sanitize();
        
        // Валидация данных
        if ($errors = $this->validate()) {
            return $errors;
        }

        // Вставляем в БД
        Database::insert($this->db_name, [
            'id_department' => $this->id_department,
            'name' => $this->name,
            'username' => $this->username,
            'password' => $this->password,
            'avatar_url' => $this->avatar_url,
            'telegram' => $this->telegram
        ]);

        return ['success' => true];
    }

    // Получение всех пользователей
    public function getAll() {
        return Database::select($this->db_name, [
            'id',
            'id_department',
            'name',
            'username',
            'avatar_url',
            'telegram'
        ]);
    }

    // Создание сессии для пользователя
    public function create_session($name_account, $password) {

        // Получаем полные данные аккаунта по переданному имени аккаунта
        $account = Database::get($this->db_name, '*', ['username' => $name_account]);


        if (!$account) {
            $this->addError('username', 'Пользователь не найден');
            return $this->getErrors();
        }

        if ($account['password'] !== $password) {
            $this->addError('password', 'Неверный пароль');
            return $this->getErrors();
        }

        $keycookies = $name_account . "_" . bin2hex(random_bytes(32));
        $week_seconds = 604800; // 1 неделя в секундах
        $data_closed = date('Y-m-d H:i:s', time() + $week_seconds);

        Database::insert($this->db_name_session, [
            'id_accounts' => $account['id'],
            'keycookies' => $keycookies,
            'data_create' => date('Y-m-d H:i:s'),
            'data_closed' => $data_closed,
            'ip_address' => $_SERVER['REMOTE_ADDR'],
            'user_agent' => $_SERVER['HTTP_USER_AGENT']
        ]);

        // Устанавливаем cookie
        setcookie('session', $keycookies, [
            'expires' => time() + $week_seconds,
            'path' => '/',
            'httponly' => true,
            'samesite' => 'Lax'
        ]);

        return [
            'success' => true,
            'keycookies' => $keycookies
        ];
    }

    // Проверка сессии и получение данных пользователя
    public function check_session($keycookies) {
        // Проверяем, что сессия не пустая
        if (!$keycookies) {
            $this->addError('session', 'Сессия не указана');
            return $this->getErrors();
        }

        // Ищем сессию
        $session = Database::get($this->db_name_session, '*', [
            'keycookies' => $keycookies,
            'data_closed[>]' => date('Y-m-d H:i:s')
        ]);

        // Проверяем, что сессия не пустая
        if (!$session) {
            $this->addError('session', 'Сессия не найдена или истекла');
            return $this->getErrors();
        }

        // Получаем данные пользователя
        $user = Database::get($this->db_name, [
            'id',
            'id_department',
            'name',
            'username',
            'avatar_url',
            'telegram'
        ], [
            'id' => $session['id_accounts']
        ]);

        if (!$user) {
            $this->addError('user', 'Пользователь не найден');
            return $this->getErrors();
        }

        return [
            'success' => true,
            'user' => $user
        ];
    }

    // Удаление только текущей сессии (logout)
    public function logout($keycookies) {
        // Проверяем, что сессия не пустая
        if (!$keycookies) {
            $this->addError('session', 'Сессия не указана');
            return $this->getErrors();
        }

        // Удаляем только текущую сессию
        Database::delete($this->db_name_session, [
            'keycookies' => $keycookies
        ]);

        // Удаляем cookie
        setcookie('session', '', [
            'expires' => time() - 3600,
            'path' => '/'
        ]);

        return ['success' => true];
    }

    // Удаление всех сессий пользователя (logout со всех устройств)
    public function logout_all($keycookies) {
        // Проверяем, что сессия не пустая
        if (!$keycookies) {
            $this->addError('session', 'Сессия не указана');
            return $this->getErrors();
        }

        // Получаем сессию чтобы узнать id пользователя
        $session = Database::get($this->db_name_session, ['id_accounts'], [
            'keycookies' => $keycookies
        ]);

        if (!$session) {
            $this->addError('session', 'Сессия не найдена');
            return $this->getErrors();
        }

        // Удаляем все сессии этого пользователя
        Database::delete($this->db_name_session, [
            'id_accounts' => $session['id_accounts']
        ]);

        // Удаляем cookie
        setcookie('session', '', [
            'expires' => time() - 3600,
            'path' => '/'
        ]);

        return ['success' => true];
    }
}

?>