<?php

namespace App\Http\Livewire;

use App\Mail\UserInfoAccountCreate;
use App\Models\Company;
use App\Models\PublicHealthEntity;
use App\Models\User;
use App\Traits\OrderByTable;
use App\Traits\QuotaRolesCompany;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Livewire\Component;
use Livewire\WithFileUploads;
use Livewire\WithPagination;

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

    public $search, $company_id, $selected_user_id, $pageTitle, $componentName, $componentNameCustom, $user_id, $search_modal, $users_modal;
    public $roleModal, $selectedCompany, $modalName, $send_mail;
    public $company_name, $company_plan_name;
    public $first_name, $last_name, $document, $phone, $email, $status, $password, $role, $image, $selected_id, $fileLoaded;
    public $title_position, $salary, $payment_method, $start_date_work, $end_date_work, $place_hired, $place_work, $work_day;
    public $eps_id, $expiration_contract, $contract_modality, $job_position_administrative_area;
    public $breadcrumb_show = true;

    private $pagination = 10;
    public $limit_users = 25;

    protected $paginationTheme = 'bootstrap';

    public function mount()
    {
        UserAuthPermission('Company_register_users_index');
        $this->company_id = Company::find(Auth::user()->CompanyId())->id;
        $this->pageTitle = 'Usuarios';
        $this->componentName = 'Empresa';
        $this->selectedState = 0;
        $this->roleModal = '';
        $this->company_name = Company::find($this->company_id )->name;
        $this->company_plan_name = Company::find($this->company_id )->plan->name;
        $this->send_mail = false;
        $this->setCompanyId($this->company_id);// obtiene el id de la empresa para usarlo en los métodos de la clase QuotaRolesCompany
        $this->roles_company_allowed();//función trait QuotaRolesCompany
    }

    public function render()
    {
        $epss = PublicHealthEntity::all();
        if (strlen($this->search) > 0)
            {

                $users= User::join('company_user', 'users.id', '=', 'company_user.user_id')
                            ->join('companies', 'company_user.company_id', '=', 'companies.id')
                            ->select('users.*','companies.name as company_name')
                            ->where('companies.id', $this->company_id)
                            ->where(function ($query) {
                            $query->where('first_name', 'like', '%' . $this->search . '%')
                                    ->orWhere('last_name', 'like', '%' . $this->search . '%')
                                    ->orWhere('document', 'like', '%' . $this->search . '%');
                            })
                            ->orderBy($this->sortBy, $this->sortDirection)->paginate($this->pagination);
            }
            else
            {
                $users= User::join('company_user', 'users.id', '=', 'company_user.user_id')
                            ->join('companies', 'company_user.company_id', '=', 'companies.id')
                            ->where('companies.id', $this->company_id)
                            ->select('users.*','companies.name as company_name')
                            ->orderBy($this->sortBy, $this->sortDirection)
                            ->paginate($this->pagination);
            }

        $this->count_reg = $users->total();

        return view('livewire.company.users.component',compact('users', 'epss'))
        ->extends('layouts.theme.admin.app')
        ->section('content');
    }


    public function openAddUser()
    {
        $this->roles_company_allowed();// lista de roles que se pueden agregar, según los roles que ya tiene la empresa, trait QuotaRolesCompany

        $this->user_id = '';
        $this->emit('show-modal', 'addUserCompany');
    }



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

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

    public function verifyRoleModal($role, $action){
        foreach ($this->roles_company_administrative as $role_company){
            if ($role_company == $role)
            {
                $role = 'Administrativo'; // Cambiar el rol a administrativo para compararlo con los permisos
            }
        }
        switch ($role) {
            case 'Administrador':
                $useractions = UserAuthPermissionActions('Company_administrator_'.$action);
            break;
            case 'Administrativo':
                $useractions = UserAuthPermissionActions('Company_administrative_'.$action);
            break;
            case 'Empleado':
                $useractions = UserAuthPermissionActions('Company_employee_'.$action);
            break;
        }

        return $useractions;
    }


    public function Store()
    {

        $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',
            'password' => 'required|min:6',
            'role' => 'required',
        ];

        $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"',
            'password.required' => 'La Contraseña es requerida',
            'password.min' => 'La Contraseña debe tener mínimo 3 caracteres',
            'role.required' => 'Seleccione el Rol para el Usuario',
        ];

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

        $useractions = $this->verifyRoleModal($this->role, 'create'); // Verificar si el usuario tiene permisos para crear usuarios de ese rol
        if (!empty($useractions)){
            $this->emit($useractions[0],$useractions[1]);
            return false;
        }

        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);

        $company = Company::find($this->company_id);
        $company->users()->attach($user->id);

        if($this->image)
        {
            $customFileName = uniqid(time(), false).'.'.$this->image->extension();
            $this->image->storeAs('public/users', $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 Edit(User $user)
    {
        $this->roles_company_all = roles_user(['Soporte', 'Super Admin']);//función helper
        $roleUser = $user->getRoleNames()[0];
        $useractions = $this->verifyRoleModal($roleUser, 'update');// Verificar si el usuario tiene permisos para editar usuarios de ese rol

        if (!empty($useractions)){
            $this->emit($useractions[0],$useractions[1]);
            return false;
        }
        if (EmployeeOtherCompany($user->id, true, false, $roleUser)[0] == NULL)
        {
            $this->emit('item-error', EmployeeOtherCompany($user->id, true)[1]);
            return false;
        }
        $this->role = $user->roles->pluck('name')->first();
        $this->selected_user_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->status = $user->status;
        $this->password = '';

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

    public function Update()
    {
        if (EmployeeOtherCompany($this->selected_user_id, true)[0] == NULL)
        {
            $this->emit('item-error', EmployeeOtherCompany($this->selected_user_id, true)[1]);
            return false;
        }

        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;
        }

        $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;
        }

        $rules = [
            'first_name' => 'required|min:3',
            'last_name' => 'required|min:3',
            'phone' => "required|unique:users,phone,{$this->selected_user_id}|min:7|max:15",
            'document' => "required|unique:users,document,{$this->selected_user_id}|min:7|max:15",
            'email' => "required||email|unique:users,email,{$this->selected_user_id}",
            'status' => 'required|not_in:Seleccionar',
            'password' => 'nullable|min:6|',
            'role' => 'required',
        ];

        $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"',
            'password.min' => 'La Contraseña debe tener mínimo 3 caracteres',
            'role.required' => 'Seleccione un Rol para el Usuario',
        ];

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

        $useractions = $this->verifyRoleModal($this->role, 'update');// Verificar si el usuario tiene permisos para actualizar usuarios de ese rol
        if (!empty($useractions)){
            $this->emit($useractions[0],$useractions[1]);
            return false;
        }

        $user = User::find($this->selected_user_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',$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/'. $imageName))//verificamos que la imagen exista fisicamente
                {
                    unlink('storage/users/' . $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',
        'sendMailInfoUserAccount'
    ];

    public function Destroy(User $user)
    {
        $current_user = Auth::user()->id;
        if ($current_user == $user->id)
        {
            $this->emit('item-error', 'No puedes eliminar tu propio usuario');
            return false;
        }
        $role_user = User::find($user->id)->roles->pluck('name')->first();//obtenemos el nombre del rol del usuario

        $useractions = $this->verifyRoleModal($role_user, 'delete'); // los nombres de los roles se validan en español, ya que asi se guardan en la base de datos
        if (!empty($useractions)){
            $this->emit($useractions[0],$useractions[1]);
            return false;
        }

        if (EmployeeOtherCompany($user->id, true)[0] == NULL)
        {
            $this->emit('item-error', EmployeeOtherCompany($user->id, true)[1]);
            return false;
        }

        if ($user)
        {
            $contracts_user = DB::table('history_contracts_users')->where('user_id',$user->id)->count();
            if ($contracts_user > 0)
            {
                $this->emit('user-withContracts', 'El usuario tiene contratos asociados');
            }
            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/'. $imageName))//verificamos que la imagen exista fisicamente
                    {
                        unlink('storage/users/' . $imageName); //eliminamos la imagen
                    }
                }
                $user->delete();
                $company = Company::find($this->company_id);
                $company->users()->detach($user->id);
                $this->resetUI();
                $this->emit('item-deleted', 'Usuario eliminado');
            }
        }
    }

    public function openJobPositionAdministrative(User $user)
    {
        $this->roles_company_all = roles_user(['Soporte', 'Super Admin']);//función helper
        $roleUser = $user->getRoleNames()[0];

        if (EmployeeOtherCompany($user->id, true, false, $roleUser)[0] == NULL)
        {
            $this->emit('item-error', EmployeeOtherCompany($user->id, true)[1]);
            return false;
        }
        $this->componentNameCustom = $user->first_name . ' ' . $user->last_name;
        $this->selected_id = $user->id;
        $company = Company::find($this->company_id)->users()->wherePivot('user_id', $this->selected_id)->get()->first();
        $this->job_position_administrative_area = $company->pivot->job_position_administrative_area;
        $this->emit('show-modal-administrative', 'jobPositionAdministrative');
    }

    public function StoreJobTitleAdministrative(){

    }

    public function UpdateJobPositionAdministrative(){
        $company = Company::find($this->company_id);
        //dd($this->selected_id, $this->job_position_administrative_area);
        $company->users()->updateExistingPivot($this->selected_id,[
            'job_position_administrative_area' => $this->job_position_administrative_area,
        ]);
        //dd($company->pivot->job_position_administrative_area);
        $this->emit('item-updated', 'Cargo Actualizado');
        $this->emit('hide-modal-administrative', '');
    }

    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');
    }
}
