<?php

namespace App\Http\Livewire;

use App\Mail\UserInfoAccountCreate;
use App\Models\User;
use App\Traits\OrderByTable;
use App\Traits\QuotaRolesCompany;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Livewire\Component;
use Livewire\WithFileUploads;
use Livewire\WithPagination;
use Spatie\Permission\Models\Role;

class UsersController extends Component
{
    use WithPagination;
    use WithFileUploads;
    use OrderByTable;
    use QuotaRolesCompany;

    public $first_name, $last_name, $document, $phone, $email, $role, $status, $password, $image, $selected_id, $roles;
    public $fileLoaded, $componentName, $pageTitle, $search, $count_reg, $send_mail, $company_user;
    public $breadcrumb_show = true;

    private $pagination = 10;
    /*
    public function paginationView()
    {
       // return 'common.paginationCustom';
       //return 'bootstrap';
    }
    */

    protected $paginationTheme = 'bootstrap';

    public function mount()
    {
        UserAuthPermission('User_index');
        $this->pageTitle = 'Listado';
        $this->componentName = 'Usuarios';
        $this->status = 'Seleccionar';
        $this->send_mail = false;
        $this->roles = Role::orderBy('id', 'asc')->get();
    }

    public function updatingSearch(){
        $this->resetPage();
    }

    public function render()
    {
        if (strlen($this->search) > 0)
        {
            $data= User::where('first_name', 'like' , '%' . $this->search . '%')
                        ->orWhere('last_name', 'like' , '%' . $this->search . '%')
                        ->orWhere('document', 'like' , '%' . $this->search . '%')
            ->select('*')->orderBy($this->sortBy, $this->sortDirection)->paginate($this->pagination);
        }
        else
        {
            $data= User::select('*')->orderBy($this->sortBy, $this->sortDirection)
            ->paginate($this->pagination);
        }

        $this->count_reg = $data->total();
        return view('livewire.users.component', compact('data'))
        ->extends('layouts.theme.admin.app')
        ->section('content');
    }

    public function openAdd()
    {
        $useractions = UserAuthPermissionActions('User_create');
        if (!empty($useractions)){
            $this->emit($useractions[0],$useractions[1]);
            return false;
        }
        $this->selected_id = 0;
        $this->resetUI();
        $this->emit('show-modal','Abrir Modal');
    }

    public function resetUI()
    {
        $this->first_name = '';
        $this->last_name = '';
        $this->document = '';
        $this->phone = '';
        $this->email = '';
        $this->password = '';
        $this->image = '';
        $this->search = '';
        $this->status ='';
        $this->selected_id = 0;
        $this->send_mail = false;
        $this->resetValidation();
        $this->resetPage();
    }

    public function Edit(User $user, $company_user)
    {
        $useractions = UserAuthPermissionActions('User_update');
        if (!empty($useractions)){
            $this->emit($useractions[0],$useractions[1]);
            return false;
        }

        $user_with_company = DB::table('company_user')->where('user_id', $user->id)->get()->first();

        if ($user_with_company)
        {
            $this->roles = roles_user(['Soporte', 'Super Admin']);
        }
        else
        {
            $this->roles = roles_user();
        }

        $role = $user->roles->pluck('name');
        $this->selected_id = $user->id;
        $this->first_name = $user->first_name;
        $this->last_name = $user->last_name;
        $this->document = $user->document;
        $this->phone = $user->phone;
        $this->email = $user->email;
        $this->role = $role;
        $this->status = $user->status;
        $this->password = '';
        $this->company_user = $company_user;

        $this->emit('show-modal', 'Abrir Modal');
    }


    public function generatePassword(){
        $this->password = generateStrongPassword();
    }

    public function Store()
    {
        $useractions = UserAuthPermissionActions('User_create');
        if (!empty($useractions)){
            $this->emit($useractions[0],$useractions[1]);
            return false;
        }
        $rules = [
            'first_name' => 'required|min:3',
            'last_name' => 'required|min:3',
            'phone' => 'required|unique:users|min:7|max:10',
            'document' => 'required|unique:users|min:7|max:15',
            'email' => 'required|unique:users|email',
            'status' => 'required|not_in:Seleccionar',
            'role' => 'required|not_in:Seleccionar',
            'password' => 'required|min:6'
        ];

        $messages = [
            'first_name.required' => 'Ingresa el Nombre',
            'first_name.min' => 'El Nombre debe tener como mínimo 3 caracteres',
            'last_name.required' => 'Ingresa el Apellido',
            'last_name.min' => 'El Apellido debe tener como mínimo 3 caracteres',
            'phone.required' => 'Ingresa el número de documento',
            'phone.min' => 'El Teléfono debe tener como mínimo 6 caracteres',
            'phone.max' => 'El Teléfono debe tener máximo 10 caracteres',
            'document.required' => 'Ingresa el número de documento',
            'document.min' => 'El Documento debe tener como mínimo 6 caracteres',
            'document.max' => 'El Documento debe tener máximo 15 caracteres',
            'document.unique' => 'El Número de documento ya esta registrado',
            'email.required' => 'Ingresa un Correo electrónico',
            'email.email' => 'Ingresa un Correo electrónico valido',
            'email.unique' => 'El Correo electrónico ya esta registrado',
            'status.required' => 'Seleccione el Estado para el Usuario',
            'status.not_in' => 'Seleccione un Estado de Usuario diferente a "Seleccionar"',
            'role.required' => 'Seleccione el Rol del Usuario',
            'role.not_in' => 'Seleccione un Rol de Usuario diferente a "Seleccionar"',
            'password.required' => 'La Contraseña es requerida',
            'password.min' => 'La Contraseña debe tener mínimo 3 caracteres'
        ];

        $this->validate($rules, $messages);

        if ($this->send_mail == true)
        {
            $passNotEncrypt = $this->password;
        }

        $user = User::create([
            'first_name' => $this->first_name,
            'last_name' => $this->last_name,
            'phone' => $this->phone,
            'email' => $this->email,
            'document' => $this->document,
            'status' => $this->status,
            'password' => bcrypt($this->password)
        ]);

        $user->syncRoles($this->role);

        if($this->image)
        {
            $customFileName = uniqid(time(), false).'.'.$this->image->extension();
            $this->image->storeAs('public/users/'.$user->id.'/', $customFileName);
            $user->image = $customFileName;
            $user->save();
        }

        if ($this->send_mail == 'true'){
            $this->sendMailInfoUserAccount($user->id, $passNotEncrypt);
            $this->emit('item-updated', 'El usuario se ha registrado correctamente, se le ha enviado un correo electrónico con su información de acceso');
        }
        else
            $this->emit('item-added', 'Usuario registrado');

        $this->resetUI();
    }

    public function Update()
    {
        $useractions = UserAuthPermissionActions('User_update');

        if ($this->send_mail == true && empty($this->password)) // Si se marcar para enviar el correo, la contraseña no puede estar vacía
        {
            $this->emit('item-error', 'Ingrese la contraseña para enviar el correo');
            return false;
        }

        if (!empty($useractions)){
            $this->emit($useractions[0],$useractions[1]);
            return false;
        }
        $rules = [
            'first_name' => 'required|min:3',
            'last_name' => 'required|min:3',
            'phone' => "required|unique:users,phone,{$this->selected_id}|min:7max:15",
            'document' => "required|unique:users,document,{$this->selected_id}|min:7|max:15",
            'email' => "required||email|unique:users,email,{$this->selected_id}",
            'status' => 'required|not_in:Seleccionar',
            'role' => 'required|not_in:Seleccionar',
            'password' => 'nullable|min:6|',
        ];

        $messages = [
            'first_name.required' => 'Ingresa el Nombre',
            'first_name.min' => 'El Nombre debe tener como mínimo 3 caracteres',
            'last_name.required' => 'Ingresa el Apellido',
            'last_name.min' => 'El Apellido debe tener como mínimo 3 caracteres',
            'phone.required' => 'Ingresa el número de documento',
            'phone.min' => 'El Teléfono debe tener como mínimo 7 caracteres',
            'phone.max' => 'El Teléfono debe tener máximo 15 caracteres',
            'document.required' => 'Ingresa el número de documento',
            'document.min' => 'El Documento debe tener como mínimo 7 caracteres',
            'document.max' => 'El Documento debe tener máximo 15 caracteres',
            'email.required' => 'Ingresa un Correo electrónico',
            'email.email' => 'Ingresa un Correo electrónico valido',
            'email.unique' => 'El Correo electrónico ya esta registrado',
            'status.required' => 'Seleccione el Estado para el Usuario',
            'status.not_in' => 'Seleccione un Estado de Usuario diferente a "Seleccionar"',
            'role.required' => 'Seleccione el Rol del Usuario',
            'role.not_in' => 'Seleccione un Rol de Usuario diferente a "Seleccionar"',
            'password.min' => 'La Contraseña debe tener mínimo 3 caracteres',
        ];

        $this->validate($rules, $messages);

        $user_with_company = DB::table('company_user')->select('company_id')->where('user_id', $this->selected_id)->first();//Obtenemos la empresa del usuario

        if ($user_with_company)//si el usuario tiene una empresa asignada
        {
            $this->roles = roles_user(['Soporte', 'Super Admin']);
            $this->setCompanyId($user_with_company->company_id);
            debug("company id: ", $user_with_company->company_id);
            $this->roles_company_allowed();// método trait QuotaRolesCompany
            $quota_role=$this->role_quota_max($this->role); // método trait QuotaRolesCompany
            if ($quota_role <= 0){
                $this->emit('item-error', 'El rol seleccionado ya tiene una cuota máxima de usuarios registrados');
                return false;
            }
        }
        $user = User::find($this->selected_id);


        if ($this->send_mail == true)
        {
            $passNotEncrypt = $this->password;
        }

        if ($this->password == ''){
            $this->password = $user->password;
        }
        else{
            $this->password = bcrypt($this->password);
        }
        $user->update([
            'first_name' => $this->first_name,
            'last_name' => $this->last_name,
            'phone' => $this->phone,
            'email' => $this->email,
            'document' => $this->document,
            'status' => $this->status,
            'password' => $this->password
        ]);

        $user->syncRoles($this->role);

        if($this->image)
        {
            $customFileName = uniqid(time(), false). '.' . $this->image->extension();
            $this->image->storeAs('public/users/'.$user->id.'/',$customFileName);
            $imageName = $user->image; //nombre de la imagen actual guardada en la base de datos

            $user->image = $customFileName; //asignamos el nuevo nombre de la imagen
            $user->save();
            //debug($imageName);
            if ($imageName != null)//si la consulta devuelve el nombre de una imagen
            {
                if(file_exists('storage/users/'.$user->id.'/'. $imageName))//verificamos que la imagen exista fisicamente
                {
                    unlink('storage/users/'.$user->id.'/' . $imageName); //eliminamos la imagen
                }
            }
        }

        if ($this->send_mail == 'true'){
            $this->sendMailInfoUserAccount($user->id, $passNotEncrypt);
            $this->emit('item-updated', 'La información se actualizó correctamente, y se envió un correo electrónico al usuario');
        }
        else
            $this->emit('item-updated', 'Usuario Actualizado');

        $this->resetUI();
    }

    protected $listeners = [
        'deleteRow' => 'Destroy',
        'resetUI' => 'resetUI',
        'send_email_info_account' => 'sendMailInfoUserAccount'
    ];

    public function Destroy(User $user)
    {
        $useractions = UserAuthPermissionActions('User_delete');
        if (!empty($useractions)){
            $this->emit($useractions[0],$useractions[1]);
            return false;
        }
        if ($user)
        {
            $companies = DB::table('company_user')->where('user_id', $user->id)->count();
            if ($companies > 0)
            {
                $this->emit('user-withCompanies', 'El usuario Esta registrado en un Empresa');
            }
            else{
                $imageName = $user->image; //nombre de la imagen actual guardada en la base de datos
                if ($imageName != null)//si la consulta devuelve el nombre de una imagen
                {
                    if(file_exists('storage/users/'.$user->id.'/'. $imageName))//verificamos que la imagen exista fisicamente
                    {
                        unlink('storage/users/'.$user->id.'/' . $imageName); //eliminamos la imagen
                    }
                }
                $user->delete();
                $this->resetUI();
                $this->emit('item-deleted', 'Usuario eliminado');
            }
        }
    }

    public function sendMailInfoUserAccount($id, $pass=null)
    {
        $user = User::find($id);
        if ($pass == null) // la variable pass tiene valor cuando se crea un nuevo usuario o se actualiza con el checkbox de enviar correo
            $password = generateStrongPassword();
        else
            $password = $pass;

        $data = [
            'first_name' => $user->first_name,
            'last_name' => $user->last_name,
            'email' => $user->email,
            'password' => $password,
            'url' =>  route('login'),
        ];
        $user->update([
            'password' => Hash::make($password)
        ]);

        Mail::to($user->email)->send(new UserInfoAccountCreate($data));
        if ($pass == null) // no se envía mensaje, ya que se usara el de la función store o update
            $this->emit('item-updated', 'Se ha enviado un correo con la información de la cuenta al usuario');
    }
}
