<?php

namespace App\Services;

use App\Repositories\Role;
use App\Repositories\User;
use Illuminate\Support\Carbon;

class UserService
{
    private $userRepository;

    public function __construct(
        User $userRepository,
        Role $roleRepository
    ) {
        $this->userRepository = $userRepository;
        $this->roleRepository = $roleRepository;
    }

    public function get($id)
    {
        return $this->userRepository->findOrFail($id);
    }

    public function getByEmailWith($email, array $children)
    {
        return $this->userRepository->where('email', $email)->with($children)->first();
    }

    public function getAll()
    {
        return $this->userRepository::all();
    }

    public function getWith(array $children, $quantity = null)
    {
        return $this->userRepository
            ->with($children)
            ->take($quantity)
            ->get();
    }

    public function with(array $children = [])
    {
        return $this->userRepository->with($children)->get();
    }

    public function getOneWith($id, array $children)
    {
        return $this->userRepository->with($children)->findOrFail($id);
    }

    public function getAllWithRoles(array $roles)
    {
        return $this->userRepository->whereHas('roles', static function ($query) use ($roles) {
            return $query->whereIn('name', $roles);
        })->get();
    }

    public function save(array $data, $isSuperAdmin = false)
    {

        if (isset($data['password'])) {
            $data['password'] = bcrypt($data['password']);
        }

        if (isset($data['id'])) {           

            $user = $this->userRepository->findOrFail($data['id']);
            if (!$user) return null;

            $user->update($data);

            // only admin can manage rules
            if ($isSuperAdmin) {
                if (isset($data['roles'])) $user->roles()->sync($data['roles']);
                else $user->roles()->sync([]);
            }
        } else {
            $user = $this->userRepository->create($data);

            //  Get user role, the default role to attach to new users
            $role = $this->roleRepository::select('id')->where('name', 'user')->first();
            $user->roles()->attach($role);
        }

        return $user;
    }

    public function delete($id)
    {
        $user = $this->get($id);
        $user->roles()->detach();
        $user->delete();
    }

    public function truncate()
    {
        return $this->userRepository->truncate();
    }
}
