<?php

namespace App;

use DB;
use Auth;

use Hash;
use Crypt;
use App\Branch;
use App\AssignDepartment;
use App\Inventory\VendorType;
use App\Inventory\Usertoproject;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;
    use HasRoles;


    /**
     * The attributes that are generic.
     *
     * @var array
     */
    private $generic_condition = [];

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

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


    public function getCondition()
    {
       $this->generic_condition = [

                     'is_recycle' => '0',
                ];

        if(isset(Auth::user()->id))
        {
            if(Auth::user()->type == "Administrator")
            {
                $this->generic_condition = [

                    'is_recycle' => '0',
                ];
            }
            elseif(Auth::user()->type == "Employee")
            {
                $this->generic_condition = [

                     'is_recycle' => '0',
                ];
            }
            else
            {
                $this->generic_condition = [

                         'is_recycle' => '0',
                    ];
            }
        }
        else
        {
            $this->generic_condition = [

                     'is_recycle' => '0',
                ];
        }

        return $this->generic_condition;
    }

    public function storeUser($object,$branch_label)
    {

    //    if($this->verifyCnicWithType($object['cnic'],$object['type']) > 0)
    //    {
    //         return 0; // User already found;
    //    }


       return  DB::transaction(function () use ($object,$branch_label)  {

            $user                  = new User;
            $user->branch_id       = $object[$branch_label];
            $user->name            = $object['full_name'];
            $user->fname           = $object['father_name'];

            $user->relation        = $object['relation'];
            $user->gender          = $object['gender'];

            $user->email           = $this->autoGenerateEmail($object['email']);
            $user->password        = $this->autoGeneratePassword($object['password']);
            $user->cnic            = ($object['cnic']);
            $user->nationality     = $object['nationality'];
            $user->occupation      = $object['occupation'];
            $user->contact         = $object['contact'];
            $user->dob             = $object['dob'];
            $user->temp_address    = $object['temporary_address'];
            $user->per_address     = $object['permanent_address'];

            $user->dp              = $this->generateImage($object['user_image']);
            // $user->type            = $object['type'];
            $user->status          = 'Active';
            $user->passport        = $object['passport'];
            $user->other_contact   = $object['other_contact'];
            $user->designation_id  = $object['designation_id'];
            $user->employee_type   = $object['employee_type'];
            $user->salary_mode     = $object['salary_mode'];
            $user->bank_branch     = $object['bank_branch'];
            $user->bank_name       = $object['bank_name'];
            $user->account_no      = $object['account_no'];
            $user->employee_form   = $object['employee_form'];
            $user->blood_group     = $object['blood_group'];
            $user->vendor_type_id  = $object['vendor_type'];



            if(isset($object['ntn']) && $object['filer'] === 'on')
            {
                $user->is_filer = 1;
                $user->ntn  = $object['ntn'];
            }


            if(isset($object['strn']))
            {
                $user->strn  = $object['strn'];
            }
            if(isset($object['incometax_date']))
            {
                $user->incometax_date  = $object['incometax_date'];
            }
            if(isset($object['saletax_date']))
            {
                $user->saletax_date  = $object['saletax_date'];
            }

            if(isset($object['agency_address'])){
                $user->agency_address  = $object['agency_address'];
            }

            if(isset($object['agency_name'])){
                $user->agency_name     = $object['agency_name'];
            }

            $user->save();

            $this->saveRoleValue($user, $object['type']);

            return with($user);


        });

    }

    public function verifyCnicWithType($cnic,$type)
    {
        return User::where($this->getCondition() + ['cnic' => $cnic, 'type' => $type])->count();
    }

    public function saveRoleValue($user, $type)
    {
        $role = Role::findOrCreate($type);
        if (isset($role->id)) {
            $user->assignRole([$role->id]);
        }
    }

    public function updateUserRight($id,$json_object)
    {
        return DB::transaction(function () use ($id,$json_object)  {

            $user = User::find($id);

            if(isset($user->id))
            {
                $user->user_rights = json_encode($json_object);

                $user->update();

                return with($user);
            }
        });
    }

    public function updateUserDesignation($user_id,$designation_id)
    {
        return DB::transaction(function () use ($user_id,$designation_id)  {

            $user = User::find($user_id);

            if(isset($user->id))
            {
                $user->designation_id = $designation_id;

                $user->update();


                return with($user);
            }
        });
    }

    public function updateUser($object,$branch_label)
    {
        return DB::transaction(function () use ($object,$branch_label)  {


            $user = User::find($object['user_id']);

            if(isset($user->id))
            {
                if($object['type'] == 'Customer')
                {

                    $user->dob             = $object['dob'];
                    $user->nationality     = $object['nationality'];
                    $user->occupation      = $object['occupation'];
                    $user->relation        = $object['relation'];
                    $user->per_address     = $object['permanent_address'];
                    $user->temp_address    = $object['temporary_address'];


                }
                else if($object['type'] == 'Administrator' || $object['type'] == 'Employee' || $object['type'] == 'Super Admin')
                {
                    $user->password        = $this->autoGeneratePassword($object['password'],$user->password);
                    $user->designation_id     = $object['designation_id'];
                }


                $user->email           = $this->autoGenerateEmail($object['email'],$user->email);
                $user->name            = $object['full_name'];

                $user->fname           = $object['father_name'];
                $user->contact         = $object['contact'];
                $user->branch_id       = $object[$branch_label];
                $user->gender          = $object['gender'];
                $user->employee_type   = $object['employee_type'];
                $user->salary_mode     = $object['salary_mode'];
                $user->bank_branch     = $object['bank_branch'];
                $user->bank_name       = $object['bank_name'];
                $user->account_no      = $object['account_no'];
                $user->employee_form   = $object['employee_form'];
                $user->passport        = $object['passport'];
                $user->other_contact   = $object['other_contact'];
                $user->per_address     = $object['permanent_address'];
                $user->temp_address    = $object['temporary_address'];
                $user->blood_group     = $object['blood_group'];
                $user->vendor_type_id  = $object['vendor_type'];



                if ( isset( $object['cnic']  ) ) {
                      $user->cnic  = $object['cnic'];
                }

                if(isset($object['ntn']) && isset($object['filer']) && $object['filer'] === 'on')
                {
                    $user->is_filer = 1;
                    $user->ntn  = $object['ntn'];
                }
                elseif( ! isset($object['filer'])){
                    $user->is_filer = 0;
                    $user->ntn  = NULL;
                }
                if(isset($object['strn']))
                {
                    $user->strn  = $object['strn'];
                }
                if(isset($object['incometax_date']))
                {
                    $user->incometax_date  = $object['incometax_date'];
                }
                if(isset($object['saletax_date']))
                {
                    $user->saletax_date  = $object['saletax_date'];
                }

                if(isset($object['agency_address'])){
                    $user->agency_address  = $object['agency_address'];
                }

                if(isset($object['agency_name'])){
                    $user->agency_name     = $object['agency_name'];
                }

                if(isset($object['status']))
                {
                    $user->status = $object['status'];
                }

                $user->update();

                // update image after succssfully userupdate
                $user->dp              = $this->generateImage($object['user_image'],$user->dp);

                $user->update();

                return with($user);

            }
            else
            {
                return 0;
            }
        });
    }

  public function removeUser($id)
    {
        return DB::transaction(function () use ($id) {

            $user = User::find($id);

            if(isset($user->id))
            {
                $user->is_recycle   = '1';
                $user->status       = 'Deactive';

                $user->update();

                return 1;
            }

            return 0;
        });
    }

    public function getUserListByType($condition)
    {
        return  User::where($this->getCondition())->whereHas('userRoles', function ($query) use ($condition) {
            $query->whereIn('name', $condition);
        })->orderBy('id', 'desc')->get();

    //    return  User::where($this->getCondition())->whereIn('type',$condition)->orderBy('id','desc')->get();
    }

    public function getUserByCnic($cnic)
    {

        $condition = $this->getCondition();
        $condition += ['cnic' => $cnic];

        $new_id = 0;

        $user = User::where($condition)->first();

        if(isset($user->id))
        {
              $user->password = NULL;
              $user->remember_token = NULL;
              $user->type = NULL;
              $user->status = NULL;
              $user->is_recycle = NULL;
              $user->created_at = NULL;
              $user->updated_at = NULL;
              $user->remember_token =NULL;
              $user->new_id = Crypt::encrypt($user->id);
              $user->id = 0;
              $user->branch_id = Crypt::encrypt($user->branch_id);
        }

        return $user;
    }

    public function getUserType()
    {
        $roles = Role::skip(1)->get();

        // $index = $roles->search('Super Admin');

        // $roles->pull($index);
        // return ['Dealer','Sub Dealer','Employee','Customer'];
        return $roles;
    //    return  User::where($this->getCondition())->distinct()->get(['type']);
    }

    public function getUserDepartment($id)
    {

          $assigned_obj = new AssignDepartment;
          $assigned_department  = $assigned_obj->getUserDepartment($id);

          return $assigned_department;

    }


    public function getUserForBiometric($cnic)
    {
        $condition = $this->getCondition();

        $condition += ['cnic' => $cnic];

        return User::where($condition)->first();
    }

     public function getUserById($id,$columns =[])
    {

        $condition = $this->getCondition();

        $condition += ['id' => $id];


         if(@count($columns) > 0)
         {
            return User::where($condition)->select($columns)->first();
         }
         else
         {
             return User::where($condition)->first();

         }
    }


    //Retrieving Salary by ID

    public function getSalaryById($id)
    {
      $condition = $this->getCondition();
      $condition  += ['id' => $id];
        return User::where($condition)->first();
    }



    // FORIGN KEY TYPE FUNCTION LIST
    public function branch()
    {
        return $this->belongsTo(Branch::class,'branch_id')->where($this->getCondition())->withDefault();
    }


      public function scale()
    {
        return $this->belongsTo(Scale::class)->where($this->getCondition())->withDefault();
    }



    // END FORIGN KEY TYPE FUNCTION LIST


    // AUTO GENERATED FUNCTION DEPENDENSIES
    public function autoGenerateEmail($email,$old_email = "")
    {
        if(trim(strlen($email)) <= 0)
        {
            if(strlen(trim($old_email)) > 0 && strlen(trim($email)) <= 0 )
            {
                $email = $old_email;
            }
            else
            {
                $max   = User::max('id');
                $email = 'estatech2019'.($max+1).'@gisplus.net';
            }

        }

        return $email;
    }

    public function autoGeneratePassword($password,$old_password = '')
    {
        if(strlen(trim($password)) <= 0)
        {
            if(strlen(trim($old_password)) > 0 && strlen(trim($password)) <= 0 )
            {
                return $old_password;
            }
            else
            {
                $max      = User::max('id');
                $password = 'estatech2019'.($max+1).'@#';
            }
        }

        return Hash::make($password);


    }




    public function generateImage($image,$loaded_image = '/graphics/logo/user.png')
    {
        if((isset($image) && trim(strlen($image)) > 0))
        {
            $image =  \EF::uploadFile($image);

        }
        else
        {
            if(strlen(trim($loaded_image)) > 0)
            {
                $image =  $loaded_image;
            }
            else
            {
               $image = '/graphics/logo/user.png';
            }
        }


        return $image;
    }

    public function designation()
    {
        return $this->belongsTo(Designation::class,'designation_id')->withDefault();
    }

  


    public function payrollDetail()
    {
        return $this->belongsTo(PayrollDetail::class)->withDefault();
    }

    public function vendorType()
    {
        return $this->belongsTo(VendorType::class,'vendor_type_id')->withDefault();
    }


    public function usertoprojectCheck($id)
    {
        $user = Auth::User();

        $result = Usertoproject::where('branch_id',$id)->where('user_id', $user->id)->count();
        if($result > 0)
        {
          return 1;
        }
        else{
          return 0;
        }
    }







    // END AUTO GENERATED FUNCTION DEPENDENSIES


// Created By Yousaf
public function getUserTypesByCnic($cnic)
{
    $condition = $this->getCondition();
    $condition += ['cnic' => $cnic];
    return User::where($condition)->first();
}

public function getCurrentUserRolesArrayWithColumn($column_name = 'name')
{
    return $this->userRoles->pluck($column_name)->toArray();
}

public function userRoles()
{
    return $this->belongsToMany(Role::class, 'role_user','user_id');
}

public function assignRole(array $roles)
{
    $this->userRoles()->sync($roles);
}

public function storeUserTypes($object)
    {
        $user = User::find($object['user_id']);

        if (isset($user->id)) {
            // just update types of found user.

            //dd($object['types']);

            $roles = Role::whereIn('name', $object['types'])->get()->pluck('id')->toArray();
            if (@count($roles) > 0) {
                //var_dump($role);
                $user->assignRole($roles);
                //die();
            }

            $user->save();
        }

        return $user;
    }

// End

}
