<?php

namespace App\Http\Livewire;

use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\Password;
use Livewire\Component;
use Livewire\WithFileUploads;
use Spatie\Permission\Models\Role;

class UserProfileController extends Component
{
    public $user_id, $first_name, $last_name, $role_user, $document, $phone, $email, $image, $signature;
    public $password, $new_password, $confirm_password, $weak_password, $roles_company_admin;
    public $breadcrumb_show = true;

    use WithFileUploads;

    public function mount()
    {
        UserAuthPermission('User_profile');
        $user = User::find(Auth::user()->id);
        $this->user_id = $user->id;
        $this->first_name = $user->first_name;
        $this->last_name = $user->last_name;
        $this->email = $user->email;
        $this->phone = $user->phone;
        $this->role_user = $user->roles()->first()->name;
        $this->pageTitle = 'Perfil';
        $this->componentName = 'Usuario';
        $this->roles_company_admin = roles_user(['Super Admin', 'Soporte', 'Empleado']);
        $this->signature = $user->signature;
    }

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

    public function render()
    {

        return view('livewire.user-profile.component')
        ->extends('layouts.theme.admin.app')
        ->section('content');
    }


    public function resetUI()
    {
        $this->new_password = '';
        $this->confirm_password = '';
        $this->image = '';
        $this->resetValidation();
        //$this->resetPage();
    }




    public function updateUser()
    {
        $useractions = UserAuthPermissionActions('User_profile_update');
        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->user_id}|min:7max:15",
            'email' => "required|email|unique:users,email,{$this->user_id}",
        ];

        $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',
            'email.required' => 'Ingresa un Correo electrónico',
            'email.email' => 'Ingresa un Correo electrónico valido',
            'email.unique' => 'El Correo electrónico ya esta registrado',
        ];

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

        $user = User::find($this->user_id);

        $user->update([
            'first_name' => $this->first_name,
            'last_name' => $this->last_name,
            'phone' => $this->phone,
            'email' => $this->email,
        ]);

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

        $this->resetUI();
        $this->emit('item-updated', 'Información actualizada correctamente');
    }

    public function saveSignature(){
        if ($this->signature == NULL) {
            $this->emit('item-error', 'No se encontró la firma');
            return false;
        }
        $user = User::find($this->user_id);
        $signature = $user->signature;
        $image_parts = explode(";base64,", $this->signature);
        $image_type_aux = explode("image/", $image_parts[0]);
        $image_type = $image_type_aux[1];
        $image_base64 = base64_decode($image_parts[1]);

        //$this->signature_file->storeAs('storage/users/' .$user_id. '/signature_contracts/' ,$signatureName);
        $folderPath = public_path('storage/users/' .$this->user_id. '/signature/');
        if (!file_exists($folderPath)) {
            mkdir($folderPath, 0777, true);
        }
        if ($signature == null) {
            $signatureName = 'signature_'.uniqid(time(), false).'_'.$this->user_id.'.'.$image_type;
        }
        else{
            $signatureName = $signature;
            if(file_exists('storage/users/'.$this->user_id.'/signature/'. $signatureName))//verificamos que la imagen exista fisicamente
            {
                unlink('storage/users/'.$this->user_id.'/signature/' . $signatureName); //eliminamos la imagen
            }
        }
            $file = $folderPath . $signatureName;
            file_put_contents($file, $image_base64);

            /** eliminar partes blancas externas de la firma */
            $im  = imagecreatefromjpeg($file);
            $cropped = imagecropauto($im, IMG_CROP_SIDES);
            if ($cropped !== false) { // in case a new image object was returned
                imagedestroy($im);    // we destroy the original image
                $im = $cropped;       // and assign the cropped image to $im
            }
            $firma = $folderPath . $signatureName;
            imagejpeg($im, $firma);
            imagedestroy($im);
            /** end */
            $user->signature = $signatureName;
            $user->save();
            return redirect()->route('perfil-usuario')->with('updated', 'Firma actualizada correctamente');
            //dd($this->signature_employee);

    }

    public function updatePassword()
    {
        $useractions = UserAuthPermissionActions('User_profile_update');
        if (!empty($useractions)){
            $this->emit($useractions[0],$useractions[1]);
            return false;
        }
        $rules = [
            'password' => 'required',
            'new_password' => 'required',
            'confirm_password' => 'required|same:new_password',
        ];

        $messages = [
            'password.required' => 'Ingresa la contraseña actual',
            'new_password.required' => 'Ingresa la nueva contraseña'
        ];
        if ($this->weak_password == false) {
            $rules['new_password'] = [Password::min(8) ->mixedCase() ->letters() -> numbers() -> symbols() ->uncompromised()];
            $messages['new_password.min'] = 'La contraseña debe tener como mínimo 8 caracteres';
            $messages['new_password.required'] = 'Ingresa la nueva contraseña';
            $messages['new_password.string'] = 'La contraseña debe ser una cadena de caracteres';
            $messages['confirm_password.required'] = 'Ingresa la confirmación de la nueva contraseña';
        }

        $messages['confirm_password.same'] = 'La confirmación de la contraseña no coincide';
        $this->validate($rules, $messages);

        $user = User::find($this->user_id);

        if (Hash::check($this->password, $user->password)) {
            $user->update([
                'password' => Hash::make($this->new_password),
                'weak_password' => $this->weak_password,
            ]);
        } else {
            $this->emit('item-error', 'La contraseña actual no coincide');
            return false;
        }

        $this->resetUI();
        $this->emit('item-updated', 'Contraseña actualizada correctamente');

    }

    public function generatePassword(){
        $this->emit('item-updated', 'Contraseña generada correctamente');
        $this->new_password = generateStrongPassword();
        $this->confirm_password = $this->new_password;
    }

}
