<?php
declare(strict_types=1);
namespace App\Controllers;

use App\Core\Controller;
use App\Core\SessionAuth;
use App\Repositories\UserRepository;

final class UsersController extends Controller {
    private UserRepository $users;

    public function __construct() {
        $this->users = new UserRepository();
    }

    private function guard(): void {
        app()->get(SessionAuth::class)->requirePageAccess('users');
    }

    public function index(): void {
        $this->guard();
        $users = $this->users->allUsers();
        $roles = $this->users->allRoles();
        $permissions = $this->users->allPermissions();
        $selectedRoleId = (int)($_GET['role_id'] ?? 0);
        $rolePermissions = [];
        if ($selectedRoleId > 0) {
            $rolePermissions = $this->users->permissionCodesByRole($selectedRoleId);
        }
        $this->view('users/index', compact('users', 'roles', 'permissions', 'selectedRoleId', 'rolePermissions'));
    }

    public function create(): void {
        $this->guard();
        $roles = $this->users->allRoles();
        $permissions = $this->users->allPermissions();
        $user = ['id'=>0,'role_id'=>2,'full_name'=>'','username'=>'','is_active'=>1];
        $this->view('users/form', [
            'title' => 'إضافة مستخدم',
            'user' => $user,
            'roles' => $roles,
            'permissions' => $permissions,
            'selectedPermissions' => [],
            'action' => base_url('?page=user_store'),
        ]);
    }

    public function store(): void {
        $this->guard();
        verify_csrf();
        $fullName = trim((string)($_POST['full_name'] ?? ''));
        $username = trim((string)($_POST['username'] ?? ''));
        $password = (string)($_POST['password'] ?? '');
        $roleId = (int)($_POST['role_id'] ?? 0);
        $isActive = isset($_POST['is_active']) ? 1 : 0;
        $permissionIds = array_map('intval', $_POST['permission_ids'] ?? []);

        if ($fullName === '' || $username === '' || $password === '' || $roleId <= 0) {
            flash('error', 'يرجى تعبئة جميع الحقول المطلوبة');
            redirect(base_url('?page=user_create'));
        }
        if ($this->users->usernameExists($username)) {
            flash('error', 'اسم المستخدم مستخدم بالفعل');
            redirect(base_url('?page=user_create'));
        }

        $this->users->createUser([
            'role_id' => $roleId,
            'full_name' => $fullName,
            'username' => $username,
            'password_hash' => password_hash($password, PASSWORD_DEFAULT),
            'is_active' => $isActive,
        ]);
        $this->users->syncRolePermissions($roleId, $permissionIds ?: $this->defaultPermissionsForRole($roleId));

        flash('success', 'تم إضافة المستخدم بنجاح');
        redirect(base_url('?page=users'));
    }

    public function edit(): void {
        $this->guard();
        $id = (int)($_GET['id'] ?? 0);
        $user = $this->users->findById($id);
        if (!$user) {
            flash('error', 'المستخدم غير موجود');
            redirect(base_url('?page=users'));
        }

        $roles = $this->users->allRoles();
        $permissions = $this->users->allPermissions();
        $selectedPermissions = $this->users->permissionCodesByRole((int)$user['role_id']);

        $this->view('users/form', [
            'title' => 'تعديل مستخدم',
            'user' => $user,
            'roles' => $roles,
            'permissions' => $permissions,
            'selectedPermissions' => $selectedPermissions,
            'action' => base_url('?page=user_update&id=' . (int)$user['id']),
        ]);
    }

    public function update(): void {
        $this->guard();
        verify_csrf();
        $id = (int)($_GET['id'] ?? 0);
        $user = $this->users->findById($id);
        if (!$user) {
            flash('error', 'المستخدم غير موجود');
            redirect(base_url('?page=users'));
        }

        $fullName = trim((string)($_POST['full_name'] ?? ''));
        $username = trim((string)($_POST['username'] ?? ''));
        $password = (string)($_POST['password'] ?? '');
        $roleId = (int)($_POST['role_id'] ?? 0);
        $isActive = isset($_POST['is_active']) ? 1 : 0;
        $permissionIds = array_map('intval', $_POST['permission_ids'] ?? []);

        if ($fullName === '' || $username === '' || $roleId <= 0) {
            flash('error', 'يرجى تعبئة جميع الحقول المطلوبة');
            redirect(base_url('?page=user_edit&id=' . $id));
        }
        if ($this->users->usernameExists($username, $id)) {
            flash('error', 'اسم المستخدم مستخدم بالفعل');
            redirect(base_url('?page=user_edit&id=' . $id));
        }

        $this->users->updateUser($id, [
            'role_id' => $roleId,
            'full_name' => $fullName,
            'username' => $username,
            'is_active' => $isActive,
        ]);

        if ($password !== '') {
            $this->users->updatePassword($id, password_hash($password, PASSWORD_DEFAULT));
        }

        $this->users->syncRolePermissions($roleId, $permissionIds ?: $this->defaultPermissionsForRole($roleId));

        if ((int)($user['id'] ?? 0) === (int)($_SESSION['uid'] ?? 0)) {
            unset($_SESSION['_perm_codes']);
        }

        flash('success', 'تم تحديث المستخدم بنجاح');
        redirect(base_url('?page=users'));
    }

    public function delete(): void {
        $this->guard();
        verify_csrf();
        $id = (int)($_POST['id'] ?? 0);
        if ($id > 0 && $id !== (int)($_SESSION['uid'] ?? 0)) {
            $this->users->deleteUser($id);
            flash('success', 'تم حذف المستخدم');
        } else {
            flash('error', 'لا يمكن حذف هذا المستخدم');
        }
        redirect(base_url('?page=users'));
    }

    private function defaultPermissionsForRole(int $roleId): array {
        $role = $this->users->findRoleById($roleId);
        $code = (string)($role['code'] ?? '');
        $all = $this->users->allPermissions();
        $mapByCode = [];
        foreach ($all as $p) $mapByCode[(string)$p['code']] = (int)$p['id'];

        return match ($code) {
            'admin' => array_values(array_map(fn($p) => (int)$p['id'], $all)),
            'reports' => array_values(array_filter([
                $mapByCode['page.dashboard'] ?? 0,
                $mapByCode['page.reports'] ?? 0,
            ])),
            default => array_values(array_filter([
                $mapByCode['page.dashboard'] ?? 0,
                $mapByCode['page.invoices'] ?? 0,
                $mapByCode['page.returns'] ?? 0,
                $mapByCode['page.customers'] ?? 0,
                $mapByCode['page.items'] ?? 0,
                $mapByCode['page.queue'] ?? 0,
                $mapByCode['page.queue_print'] ?? 0,
                $mapByCode['page.queue_manage'] ?? 0,
                $mapByCode['page.tailoring'] ?? 0,
                $mapByCode['page.tailoring_create'] ?? 0,
                $mapByCode['page.tailoring_orders'] ?? 0,
                $mapByCode['page.studio'] ?? 0,
                $mapByCode['page.studio_create'] ?? 0,
                $mapByCode['page.studio_manage'] ?? 0,
            ])),
        };
    }
}
