<?php 

namespace App\Services;

use Illuminate\Support\Facades\Storage;
use App\Http\Resources\UserResource;
use App\Http\Resources\StaffResource;
use Illuminate\Support\Str;
use App\Models\MediaType;
use App\Models\SourceType;
use App\Models\Media;
use App\Models\User;
use App\Models\Department;
use App\Models\Staff;
use App\Models\Payroll;
use Hash;
use Image;
use Log;

class UserService{
    

    public function get(){
        // $users = User::where('super_admin', '<>', 1)->where('group','ADMIN')->get();
        $users = Staff::whereHas('user', function($q){
            $q->where('super_admin', '<>', 1)
                ->where('group', 'ADMIN');
        })->get();
        return StaffResource::collection($users);
    }

    /**
     * create
     *
     * @param  mixed $request
     * @return void
     */
    public function create($request){

        if($request->has_account){
            $user = new User();
            $user->email = $request->email;
            $user->password = Hash::make($request->password);        
            $user->group = 'ADMIN';  
            $user->save();
            $user->syncRoles($request->roles ?? []);      
        }

        $member = new Staff();
        $member->code = $request->code;
        $member->cnic = $request->cnic;
        $member->title = $request->title;
        $member->first_name = $request->first_name;
        $member->last_name = $request->last_name;
        $member->department = $request->department;
        $member->address = $request->address;
        $member->campus_id = $request->campus_id ?? null;
        $member->contacts = ['primary' => $request->phone, 'secondary' => $request->secondary_phone ?? ""];
        $member->user_id = isset($user) ? $user->id : null;
        $member->save();

        if($request->has_payroll){
            $payroll = new Payroll();
            if($request->joined_at){
                $payroll->joined_at = date('Y-m-d H:i:s', strtotime($request->joined_at));
            }
            $payroll->basic_salary = $request->basic_salary;
            $payroll->allowances = $request->allowances ?? [];
            $payroll->staff_id = $member->id;
            $payroll->save();
        }

        $avatar_path = self::_get_avatar_path($request);    
        if($avatar_path){
            $avatar_path['mediable_id']     = $member->id;
            $avatar_path['mediable_type']   = SourceType::STAFF;
            Media::create($avatar_path);
        }

        $documents = self::_get_documents_path($request);
        if(count($documents) > 0){
            foreach($documents as $doc){
                $doc['mediable_id'] = $member->id;
                $doc['mediable_type'] = SourceType::STAFF;
                Media::create($doc);
            }
        }

        if($request->has('department') && $request->department != ''){
            Department::updateOrCreate(['title' => ucwords($request->department) ], ['title' => ucwords($request->department) ] );
        }
        return new StaffResource($member);
    }

   

    /**
     * update
     *
     * @param  mixed $request
     * @return void
     */
    public function update($request, $id){
            
        if($request->has_account){
            $user = User::find($request->user_id);
            $user->email = $request->email;
            if($request->change_password){
                $user->password = Hash::make($request->password);
            }
            $user->save();
            $user->syncRoles($request->roles ?? []);      
        }

        $member = Staff::find($id);
        $member->code = $request->code;
        $member->cnic = $request->cnic;
        $member->title = $request->title;
        $member->first_name = $request->first_name;
        $member->last_name = $request->last_name;
        $member->department = $request->department;
        $member->address = $request->address;
        $member->campus_id = $request->campus_id ?? null;
        $member->contacts = ['primary' => $request->phone, 'secondary' => $request->secondary_phone ?? ""];
        $member->user_id = isset($user) ? $user->id : null;
        

        if($request->has_avatar == "false"){
            MediaService::remove($member->id, SourceType::STAFF, 'AVATAR');
        }

        $member->save();

        $avatar_path = self::_get_avatar_path($request);    

        if($avatar_path){
            $avatar_path['mediable_id']     = $member->id;
            $avatar_path['mediable_type']   = SourceType::STAFF;
            Media::create($avatar_path);
        }

        $documents = self::_get_documents_path($request);        
        if(count($documents) > 0){
            foreach($documents as $doc){
                $doc['mediable_id'] = $user->id;
                $doc['mediable_type'] = SourceType::STAFF;
                Media::create($doc);
            }
        }

        if($request->has('department') && $request->department != ''){
            Department::updateOrCreate(['title' => ucwords($request->department) ], ['title' => ucwords($request->department) ] );
        }
        return new StaffResource($member);        
    }
    
    /**
     * delete
     *
     * @param  mixed $id
     * @return void
     */
    public function delete($id){
        $user = User::find($id);
        $user->delete();
        return $id;
    }

    
    public function users_by_permissions($permissions=[]){
        $users = User::whereHas('roles', function($q) use($permissions){
                        $q->whereHas('permissions', function($p) use($permissions){
                            $p->whereIn('name', $permissions);
                        });
                    })->get();
        return UserResource::collection($users);
    }

    /**
     * _get_avatar_path
     *
     * @param  mixed $request
     * @return void
     */
    public function _get_avatar_path($request){
        $avatar_path = null;              
        if($request->has('avatar') && $request->file('avatar') != null)
        {
            $avatar = $request->file('avatar');
            $imageThumb = Image::make($avatar);  
            $image_thumb = $imageThumb->fit(256,256, function($constraint) {
                $constraint->upsize();
            });
            $extension = $avatar->getClientOriginalExtension();
            $namewithextension = $avatar->getClientOriginalName();                            
            $filename = 'avatar-'.Str::uuid() . '.' . $extension;
            $path = app()->basePath('public/assets/avatars/');
            $image_thumb->save($path . $filename);
            $avatar_path = '/public/assets/avatars/'.$filename;

            $file_type = $avatar->getClientMimeType();
            $data = [
                'name'          =>  $filename,
                'original_name' =>  $namewithextension,
                'path'          =>  $avatar_path,
                'extension'     =>  $extension,
                'type'          =>  MediaType::AVATAR,
                'file_type'     =>  $file_type,
            ];
                    
            return $data;
        }
        return null;
    }

    public function _get_documents_path($request){
        $docs = [];
        $exts=['pdf','jpg','png','docx','doc','jpeg','ppt','xlsx','xls'];

        if($request->has('documents') && $request->file('documents') != null){
            $files = $request->file('documents');
            foreach($files as $file){
                $filename = $file->getClientOriginalName();
                $extension = $file->getClientOriginalExtension();
                $new_filename = 'doc-'.Str::uuid().'.'.$extension;
                $check=in_array($extension,$exts);
                if($check){
                    $path = Storage::disk('documents')->putFileAs("/", $file, $new_filename);
                    $file_type = $file->getClientMimeType();
                    $docs[] = [
                        'name'          =>  $new_filename,
                        'original_name' =>  $filename,
                        'path'          =>  Storage::disk('documents')->url($path),
                        'extension'     =>  $extension,
                        'type'          =>  MediaType::DOC,
                        'file_type'     =>  $file_type,
                        'size'          =>  Storage::disk('documents')->size($path),
                    ];
                }
            }
        }

        return $docs;
        
    }
}