<?php

namespace App\Services;

use App\Models\User;
use App\Repositories\Eloquent\UserRepository;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;

class UserService
{
    protected UserRepository $userRepository;
    protected LoggingService $loggingService;

    public function __construct(UserRepository $userRepository, LoggingService $loggingService)
    {
        $this->userRepository = $userRepository;
        $this->loggingService = $loggingService;
    }

    public function getAllUsers(int $perPage = 15): LengthAwarePaginator
    {
        $this->loggingService->logService('UserService::getAllUsers');
        return $this->userRepository->with(['roles', 'branch'])->paginate($perPage);
    }

    public function getUser(int $id): User
    {
        $this->loggingService->logService('UserService::getUser', ['id' => $id]);
        return $this->userRepository->with(['roles', 'permissions', 'branch'])->findOrFail($id);
    }

    public function assignRole(int $userId, string $role): User
    {
        $this->loggingService->logService('UserService::assignRole', ['user_id' => $userId, 'role' => $role]);

        $user = User::findOrFail($userId);
        $user->assignRole($role);

        $this->loggingService->logService('UserService::assignRole', null, "Role {$role} assigned to user {$userId}");
        return $user->load(['roles', 'permissions']);
    }

    public function revokeRole(int $userId, string $role): User
    {
        $this->loggingService->logService('UserService::revokeRole', ['user_id' => $userId, 'role' => $role]);

        $user = User::findOrFail($userId);
        $user->removeRole($role);

        $this->loggingService->logService('UserService::revokeRole', null, "Role {$role} revoked from user {$userId}");
        return $user->load(['roles', 'permissions']);
    }

    public function getUserPermissions(int $userId): array
    {
        $this->loggingService->logService('UserService::getUserPermissions', ['user_id' => $userId]);

        $user = User::findOrFail($userId);
        return $user->getAllPermissions()->pluck('name')->toArray();
    }

    public function createUser(array $data): User
    {
        $this->loggingService->logService('UserService::createUser', ['email' => $data['email']]);

        $user = User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
            'branch_id' => $data['branch_id'] ?? null,
        ]);

        // Assign roles if provided
        if (!empty($data['roles'])) {
            $user->syncRoles($data['roles']);
        }

        $this->loggingService->logService('UserService::createUser', null, "User created: {$user->id}");
        return $user->load(['roles', 'permissions', 'branch']);
    }

    public function updateUser(int $id, array $data): User
    {
        $this->loggingService->logService('UserService::updateUser', ['id' => $id]);

        $user = User::findOrFail($id);

        $updateData = [
            'name' => $data['name'] ?? $user->name,
            'email' => $data['email'] ?? $user->email,
            'branch_id' => array_key_exists('branch_id', $data) ? $data['branch_id'] : $user->branch_id,
        ];

        // Update password if provided
        if (!empty($data['password'])) {
            $updateData['password'] = bcrypt($data['password']);
        }

        $user->update($updateData);

        // Sync roles if provided
        if (isset($data['roles'])) {
            $user->syncRoles($data['roles']);
        }

        $this->loggingService->logService('UserService::updateUser', null, "User updated: {$user->id}");
        return $user->load(['roles', 'permissions', 'branch']);
    }

    public function deleteUser(int $id): bool
    {
        $this->loggingService->logService('UserService::deleteUser', ['id' => $id]);

        $user = User::findOrFail($id);
        $user->delete();

        $this->loggingService->logService('UserService::deleteUser', null, "User deleted: {$id}");
        return true;
    }
}
