<?php
declare(strict_types=1);

namespace Celena\Module\Users;

use Celena\Core\Database\Connection;
use Celena\Core\Http\Pagination;
use Celena\Core\Http\Request;
use Celena\Core\Http\Response;
use Celena\Core\Security\Auth;
use Celena\Core\Security\Csrf;
use Celena\Core\Security\Filter;
use Celena\Core\Security\Password;
use Celena\Core\Security\Permission;
use Celena\Core\Template\Engine;
use Celena\Module\AdminBase\AdminController;
use Celena\Module\Settings\Options;

/**
 * CRUD пользователей. Доступ — только admin (проверка через Permission::can).
 */
final class UsersController extends AdminController
{
    public function __construct(
        Engine $engine,
        Auth $auth,
        Options $options,
        private readonly Connection $conn,
    ) {
        parent::__construct($engine, $auth, $options);
    }

    public function index(Request $request): Response
    {
        if (!Permission::can($this->auth->user(), 'users.read')) {
            return $this->redirect('/admin', 'Доступ запрещён.', 'error');
        }
        $page = Filter::int($request->query('page', 1), 1);
        // Покупатели (role=customer) — это посетители фронта (личный кабинет /account),
        // а не сотрудники. В списке штатных пользователей их не показываем.
        $total = $this->conn->builder('celena_users')->where('role', '!=', 'customer')->count();
        $p = new Pagination($page, 20, $total);
        $users = $this->conn->builder('celena_users')
            ->where('role', '!=', 'customer')
            ->orderBy('id', 'desc')
            ->limit($p->perPage)
            ->offset($p->offset)
            ->get();
        return $this->view('admin/users/index', [
            'users' => $users,
            'pagination' => $p->toArray('/admin/users?page=:page'),
        ], 'users', 'Пользователи');
    }

    public function create(Request $request): Response
    {
        if (!Permission::can($this->auth->user(), 'users.create')) {
            return $this->redirect('/admin', 'Доступ запрещён.', 'error');
        }
        return $this->view('admin/users/form', [
            'user_row' => ['id' => 0, 'email' => '', 'name' => '', 'role' => 'user', 'is_active' => true],
            'roles' => Permission::roles(),
            'form_action' => '/admin/users/create',
            'is_edit' => false,
        ], 'users', 'Новый пользователь');
    }

    public function store(Request $request): Response
    {
        if (!Permission::can($this->auth->user(), 'users.create')) {
            return $this->redirect('/admin', 'Доступ запрещён.', 'error');
        }
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/users/create', 'CSRF.', 'error');
        }
        $email = Filter::email($request->input('email'));
        $name = Filter::string($request->input('name'), 191);
        $role = Filter::in($request->input('role'), Permission::roles(), 'user');
        $pass = (string) $request->input('password');
        $active = Filter::bool($request->input('is_active'));

        if ($email === null || $name === '' || strlen($pass) < 8) {
            return $this->redirect('/admin/users/create', 'Проверьте email, имя и пароль (от 8 символов).', 'error');
        }
        $exists = $this->conn->builder('celena_users')->where('email', '=', $email)->first();
        if ($exists !== null) {
            return $this->redirect('/admin/users/create', 'Пользователь с таким email уже существует.', 'error');
        }
        $now = date('Y-m-d H:i:s');
        $this->conn->builder('celena_users')->insert([
            'email' => $email,
            'password_hash' => Password::hash($pass),
            'name' => $name,
            'role' => $role,
            'is_active' => $active,
            'locale' => 'ru',
            'created_at' => $now,
            'updated_at' => $now,
        ]);
        return $this->redirect('/admin/users', 'Пользователь создан.');
    }

    public function edit(Request $request, array $params): Response
    {
        if (!Permission::can($this->auth->user(), 'users.update')) {
            return $this->redirect('/admin', 'Доступ запрещён.', 'error');
        }
        $id = Filter::int($params['id'] ?? 0);
        $user = $this->conn->builder('celena_users')->where('id', '=', $id)->first();
        if ($user === null) {
            return $this->redirect('/admin/users', 'Пользователь не найден.', 'error');
        }
        return $this->view('admin/users/form', [
            'user_row' => $user,
            'roles' => Permission::roles(),
            'form_action' => '/admin/users/' . $id . '/update',
            'is_edit' => true,
        ], 'users', 'Редактировать: ' . $user['name']);
    }

    public function update(Request $request, array $params): Response
    {
        if (!Permission::can($this->auth->user(), 'users.update')) {
            return $this->redirect('/admin', 'Доступ запрещён.', 'error');
        }
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/users', 'CSRF.', 'error');
        }
        $id = Filter::int($params['id'] ?? 0);
        $user = $this->conn->builder('celena_users')->where('id', '=', $id)->first();
        if ($user === null) {
            return $this->redirect('/admin/users', 'Пользователь не найден.', 'error');
        }
        $name = Filter::string($request->input('name'), 191);
        $email = Filter::email($request->input('email'));
        $role = Filter::in($request->input('role'), Permission::roles(), (string) $user['role']);
        $active = Filter::bool($request->input('is_active'));
        $pass = (string) $request->input('password', '');

        if ($email === null || $name === '') {
            return $this->redirect('/admin/users/' . $id . '/edit', 'Проверьте email и имя.', 'error');
        }
        $data = [
            'email' => $email,
            'name' => $name,
            'role' => $role,
            'is_active' => $active,
            'updated_at' => date('Y-m-d H:i:s'),
        ];
        if ($pass !== '') {
            if (strlen($pass) < 8) {
                return $this->redirect('/admin/users/' . $id . '/edit', 'Пароль от 8 символов.', 'error');
            }
            $data['password_hash'] = Password::hash($pass);
        }
        $this->conn->builder('celena_users')->where('id', '=', $id)->update($data);
        return $this->redirect('/admin/users', 'Сохранено.');
    }

    public function delete(Request $request, array $params): Response
    {
        if (!Permission::can($this->auth->user(), 'users.delete')) {
            return $this->redirect('/admin', 'Доступ запрещён.', 'error');
        }
        if (!Csrf::validate((string) $request->input('_csrf'))) {
            return $this->redirect('/admin/users', 'CSRF.', 'error');
        }
        $id = Filter::int($params['id'] ?? 0);
        if ($id === $this->auth->id()) {
            return $this->redirect('/admin/users', 'Нельзя удалить самого себя.', 'error');
        }
        $this->conn->builder('celena_users')->where('id', '=', $id)->delete();
        return $this->redirect('/admin/users', 'Пользователь удалён.');
    }
}
