<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Http\Request;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Spatie\Permission\Traits\HasRoles;
use Spatie\Permission\Traits\HasPermissions;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use App\Models\UserActivityLog;
use App\Models\LogList;
use Illuminate\Support\Facades\URL;

class User extends Authenticatable
{
    use Notifiable, HasRoles, HasPermissions, HasFactory;


    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'major', 'password', 'username', 'first_name', 'last_name', 'position', 'mobile', 'province_id', 'city_id', 'confirmed', 'enabled', 'avatar', 'city_fa', 'province_fa', 'degree'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function addActivity($description)
    {
        // $temp = new UserActivityLog();
        // $temp->description = $description;
        // $temp->user_id = $this->id;
        // $temp->save();
    }

    public function test()
    {
        // dd(explode("?", request()->fullUrl())[1]);
    }

    public function addActivityComplete($log_unique_code, $model = null)
    {
//        DB::beginTransaction();

        try {
            DB::transaction(function () use ($log_unique_code, $model) {
                $temp = new UserActivityLog();
                $temp->user_id = $this->id;
                $temp->username = $this->username;
                $temp->user_name = $this->name;
                $temp->user_first_name = $this->first_name;
                $temp->user_last_name = $this->last_name;
                $temp->position = $this->position;
                $temp->mobile = $this->mobile;
                $temp->province_id = $this->province_id;
                $temp->province_fa = $this->province_fa;
                $temp->city_id = $this->city_id;
                $temp->city_fa = $this->city_fa;

                $log = LogList::where('log_unique_code', $log_unique_code)->first();
                $temp->log_unique_code = $log_unique_code;
                $temp->description = $log->description;
                $temp->action_type = $log->action_type;

                $temp->agent = request()->header('user-agent') ?? null;
                $temp->method = request()->method() ?? null;
                $temp->ip = request()->ip() ?? null;
                $temp->url = request()->Url() ?? null;
                $temp->query_parameter = serialize(request()->all());

                $temp->model = serialize($model) ?? null;
                $temp->save();
            });
//            DB::commit();
        } catch (\Throwable $th) {
//            DB::rollBack();
            try {
                DB::transaction(function () use ($log_unique_code, $model) {
                    $temp = new UserActivityLog();
                    $temp->user_id = $this->id;
                    $temp->username = $this->username;
                    $temp->user_name = $this->name;
                    $temp->user_first_name = $this->first_name;
                    $temp->user_last_name = $this->last_name;
                    $temp->position = $this->position;
                    $temp->mobile = $this->mobile;
                    $temp->province_id = $this->province_id;
                    $temp->province_fa = $this->province_fa;
                    $temp->city_id = $this->city_id;
                    $temp->city_fa = $this->city_fa;

                    $log = LogList::where('log_unique_code', $log_unique_code)->first();
                    $temp->log_unique_code = $log_unique_code;
                    $temp->description = $log->description;
                    $temp->action_type = $log->action_type;

                    $temp->agent = request()->header('user-agent') ?? null;
                    $temp->method = request()->method() ?? null;
                    $temp->ip = request()->ip() ?? null;
                    $temp->url = request()->Url() ?? null;
                    $temp->query_parameter = serialize(request()->input());

                    $temp->model = serialize($model) ?? null;
                    $temp->save();
                });
//                DB::commit();
            } catch (\Throwable $th) {
//                DB::rollBack();
                DB::transaction(function () use ($log_unique_code, $model) {
                    $temp = new UserActivityLog();
                    $temp->user_id = $this->id;
                    $temp->username = $this->username;
                    $temp->user_name = $this->name;
                    $temp->user_first_name = $this->first_name;
                    $temp->user_last_name = $this->last_name;
                    $temp->position = $this->position;
                    $temp->mobile = $this->mobile;
                    $temp->province_id = $this->province_id;
                    $temp->province_fa = $this->province_fa;
                    $temp->city_id = $this->city_id;
                    $temp->city_fa = $this->city_fa;

                    $log = LogList::where('log_unique_code', $log_unique_code)->first();
                    $temp->log_unique_code = $log_unique_code;
                    $temp->description = $log->description;
                    $temp->action_type = $log->action_type;

                    $temp->agent = request()->header('user-agent') ?? null;
                    $temp->method = request()->method() ?? null;
                    $temp->ip = request()->ip() ?? null;
                    $temp->url = request()->Url() ?? null;
                    $temp->query_parameter = "Request is to big !!!!!";

                    $temp->model = serialize($model) ?? null;
                    $temp->save();
                });
//                DB::commit();
            }
        }
        
    }

    public function getUserPermissions()
    {
        $permissions = $this->permissions;
        
        $arrayPermission = [];
        foreach ($permissions as $permission) {
            $arrayPermission[] = $permission->name;
        }

        return $arrayPermission;
    }

    // A person is Randd member iff he/she only has randd permissions and not other permissions.
    public function isRandDMember() 
    {
        return $this->permissions()->where('type','randd')->get()->count() && $this->permissions()->where('type','<>','randd')->get()->count() == 0;
    }

    public function checkUserHasPermission($permission)
    {
        return $this->checkPermissionTo($permission);
    }


    public function roadItemsProjects()
    {
        return $this->hasMany('App\Models\RoadItemsProject');
    }

    public function roadConstructionProjects()
    {
        return $this->hasMany('App\Models\RoadConstructionProject');
    }

    public function roadPatrolProjects()
    {
        return $this->hasMany('App\Models\RoadPatrolProject');
    }

    public function activityLogs()
    {
        return $this->hasMany('App\Models\UserActivityLog','user_id');
    }

    public function province()
    {
        return $this->belongsTo('App\Models\Province', 'province_id');
    }

    public function city()
    {
        return $this->belongsTo('App\Models\City', 'city_id');
    }

    public function eventHistories()
    {
        return $this->hasMany('App\Models\RmsEventHistory');
    }

    public function roadMaintenanceProjects()
    {
        return $this->hasMany('App\Models\RoadMaintenanceProject');
    }

    public function roadConstructionRural()
    {
        return $this->hasMany('App\Models\RoadConstructionRural');
    }

    public function avatarUrl(): ?string
    {
        
        $avatar = $this->attributes['avatar'];
        return $avatar == null ? null : URL::to('/') . '/' . $avatar;
    }
}