<?php

namespace App\Http\Controllers;


use Illuminate\Http\Request;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use Illuminate\Support\Facades\Storage;
use App\Models\User;
use App\Models\Branch;
use App\Models\Department;
use App\Models\Teammaster;
use App\Imports\ImportUser;
use App\Exports\ExportUser;
use App\Http\Requests\UserRequest;
use Maatwebsite\Excel\Facades\Excel;
use Auth, DB, Mail, Validator, File, DataTables, Exception;
use Carbon\Carbon;

class UserController extends Controller{
    /** construct */
        public function __construct(){
            $this->middleware('permission:user-create', ['only' => ['create']]);
            $this->middleware('permission:user-edit', ['only' => ['edit']]);
            $this->middleware('permission:user-view', ['only' => ['view']]);
            $this->middleware('permission:user-delete', ['only' => ['delete']]);
        }
    /** construct */

    /** index */
        // public function index(Request $request){
        //     if ($request->ajax()) {
        //           /* $data = User::orderBy('id', 'desc')->where('status','!=','deleted')->whereHas('roles', function ($query) {
        //             $query->where('id', '!=', 41);
        //         })->get(); */
        //         $data = User::orderBy('id', 'desc')
        //             ->where('status', '!=', 'deleted')
        //             ->whereHas('roles', function ($query) {
        //                 $query->where('id', '!=', 41);
        //             })
        //             ->get() // Fetch the users
        //           ->map(function ($user) {
        //                 // Add a calculated field for days since joining
        //                 $user->days_since_joining = $user->joining_date
        //                     ? Carbon::parse($user->joining_date)->diffInDays(Carbon::now())
        //                     : 0; // Handle null joining_date
        //                     // dd($user);
        //                 return $user;
        //             });
        //         return Datatables::of($data)
        //             ->addIndexColumn()
        //             ->addColumn('branch', function ($data) {
        //                 $branchIds = explode(',', $data->branch);
        //                 $branchNames = Branch::whereIn('id', $branchIds)->pluck('name')->implode(', ');
        //                 return $branchNames;
        //             })
        //             ->addColumn('action', function ($data) {
        //                 $return = '<div class="btn-group">';

        //                 if (auth()->user()->can('user-view')) {
        //                     $return .=  '<a href="'.route('user.view', ['id' => base64_encode($data->id)]).'" class="btn btn-default btn-xs">
        //                                         <i class="fa fa-eye"></i>
        //                                     </a> &nbsp;';
        //                 }

        //                 if (auth()->user()->can('user-edit')) {
        //                     $return .= '<a href="'.route('user.edit', ['id' => base64_encode($data->id)]).'" class="btn btn-default btn-xs">
        //                                         <i class="fa fa-edit"></i>
        //                                     </a> &nbsp;';
        //                 }

        //                 if (auth()->user()->can('user-delete')) {
        //                     $return .= '<a href="javascript:;" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown">
        //                                         <i class="fa fa-bars"></i>
        //                                     </a> &nbsp;
        //                                     <ul class="dropdown-menu">
        //                                         <li><a class="dropdown-item" href="javascript:;" onclick="change_status(this);" data-status="active" data-id="' . base64_encode($data->id) . '">Active</a></li>
        //                                         <li><a class="dropdown-item" href="javascript:;" onclick="change_status(this);" data-status="inactive" data-id="' . base64_encode($data->id) . '">Inactive</a></li>
        //                                         <li><a class="dropdown-item" href="javascript:;" onclick="change_status(this);" data-status="deleted" data-id="' . base64_encode($data->id) . '">Delete</a></li>
        //                                         <li><a class="dropdown-item" href="'.route('user.team_transfer', ['id' => base64_encode($data->id)]).'">Team Transfer</a></li>
        //                                     </ul>';
        //                 }

        //                 $return .= '</div>';

        //                 return $return;
        //             })
            
        //             ->editColumn('status', function ($data) {
                        
        //                 if ($data->status == 'active') {
        //                     return '<span class="badge badge-pill badge-success">Active</span>';
        //                 } else if ($data->status == 'inactive') {
        //                     return '<span class="badge badge-pill badge-warning">Inactive</span>';
        //                 } else if ($data->status == 'deleted') {
        //                     return '<span class="badge badge-pill badge-danger">Deleted</span>';
        //                 } else {
        //                     return '-';
        //                 }
        //             })

        //             ->editColumn('name', function ($data) {
                        
        //                     return $data->first_name.' '.$data->last_name;
                        
        //             })

        //             ->editColumn('role', function ($data) {
        //                 if(!empty($data->roles->first()->name)){
        //                     return ucfirst(str_replace('_', ' ', $data->roles->first()->name));
        //                 }else{
        //                     return null;
        //                 }
                        
        //             })
                    
        //             ->editColumn('department', function ($data) {
        //                 $department = Department::where(['id' => $data->department_id])->first();
        //                 if(!empty($department)){
        //                     return $department['name'];
        //                 }else{
        //                     return '';
        //                 }
                        
                        
        //             })

        //             ->rawColumns(['name', 'role', 'action', 'status','branch'])
        //             ->make(true);
        //     }
            
        //     return view('user.index');
        // }
        public function index(Request $request){
            if ($request->ajax()) {
                $data = User::selectRaw("users.*, IFNULL(DATEDIFF(NOW(), users.joining_date), 0) as days_since_joining")
                ->orderBy('id', 'desc')
                    ->where('status', '!=', 'deleted');
                    // ->whereHas('roles', function ($query) {
                    //     $query->where('id', '!=', 41);
                    // });
                return Datatables::of($data)
                    ->addIndexColumn()
                    ->addColumn('action', function ($data) {
                        $return = '<div class="btn-group">';

                        if (auth()->user()->can('user-view')) {
                            $return .=  '<a href="'.route('user.view', ['id' => base64_encode($data->id)]).'" class="btn btn-default btn-xs">
                                                <i class="fa fa-eye"></i>
                                            </a> &nbsp;';
                        }

                        if (auth()->user()->can('user-edit')) {
                            $return .= '<a href="'.route('user.edit', ['id' => base64_encode($data->id)]).'" class="btn btn-default btn-xs">
                                                <i class="fa fa-edit"></i>
                                            </a> &nbsp;';
                        }

                        if (auth()->user()->can('user-delete')) {
                            $return .= '<a href="javascript:;" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown">
                                                <i class="fa fa-bars"></i>
                                            </a> &nbsp;
                                            <ul class="dropdown-menu">
                                                <li><a class="dropdown-item" href="javascript:;" onclick="change_status(this);" data-status="active" data-id="' . base64_encode($data->id) . '">Active</a></li>
                                                <li><a class="dropdown-item" href="javascript:;" onclick="change_status(this);" data-status="inactive" data-id="' . base64_encode($data->id) . '">Inactive</a></li>
                                                <li><a class="dropdown-item" href="javascript:;" onclick="change_status(this);" data-status="deleted" data-id="' . base64_encode($data->id) . '">Delete</a></li>
                                                <li><a class="dropdown-item" href="'.route('user.team_transfer', ['id' => base64_encode($data->id)]).'">Team Transfer</a></li>
                                            </ul>';
                        }

                        $return .= '</div>';

                        return $return;
                    })

                    ->addColumn('branch', function ($data) {
                        $branchIds = explode(',', $data->branch);
                        $branchNames = Branch::whereIn('id', $branchIds)->pluck('name')->implode(',<br>');
                        return $branchNames;
                    })
            
                    ->editColumn('status', function ($data) {
                        
                        if ($data->status == 'active') {
                            return '<span class="badge badge-pill badge-success">Active</span>';
                        } else if ($data->status == 'inactive') {
                            return '<span class="badge badge-pill badge-warning">Inactive</span>';
                        } else if ($data->status == 'deleted') {
                            return '<span class="badge badge-pill badge-danger">Deleted</span>';
                        } else {
                            return '-';
                        }
                    })

                    ->editColumn('name', function ($data) {
                        
                            return $data->first_name.' '.$data->last_name;
                        
                    })

                    ->editColumn('role', function ($data) {
                        if(!empty($data->roles->first()->name)){
                            return ucfirst(str_replace('_', ' ', $data->roles->first()->name));
                        }else{
                            return null;
                        }
                        
                    })
                    
                    ->editColumn('department', function ($data) { 
                        $department = Department::where(['id' => $data->department_id,'status' => 'active'])->first();
                        if(!empty($department)){
                            return $department['name'];
                        }else{
                            return '';
                        }
                        
                        
                    })

                    ->rawColumns(['name', 'role', 'action', 'status','branch'])
                    ->filter(function ($query){
                        if (request()->get('name',false)) {
                            $salesPersonName = request()->get('name');
                            $query->whereRaw("CONCAT(users.first_name, ' ', users.last_name) LIKE ?", ["%{$salesPersonName}%"]);
                        }
                        if (request()->get('role',false)) {
                            $role = request()->get('role');
                            $query->whereHas('roles', function ($q) use ($role) {
                                $q->where('name', 'LIKE', "%{$role}%");
                            });
                        }
                        if (request()->get('department', false)) {
                            $department = request()->get('department');
                            $query->whereHas('department', function ($q) use ($department) {
                                $q->where('name', 'LIKE', "%{$department}%");
                            });
                        }
                        if (request()->get('branch',false)) {
                            $branch = request()->get('branch');
                            $query->whereHas('branch', function ($q) use ($branch) {
                                $q->where('name', 'LIKE', "%{$branch}%");
                            });
                        }
                        if (request()->get('contact_number',false)) {
                            $query->where('users.contact_number', "like", "%".request()->get("contact_number")."%");
                        }
                        if (request()->get('email',false)) {
                            $query->where('users.email', "like", "%".request()->get("email")."%");
                        } 
                    })    
                    ->make(true);
            }
            
            return view('user.index');
        }
    /** index */
    
    /** Trash */
        public function Trash(Request $request){
            if ($request->ajax()) {
                $data = User::orderBy('id', 'desc')->where('status','=','deleted')->get();
                
                return Datatables::of($data)
                    ->addIndexColumn()
                    ->addColumn('action', function ($data) {
                        $return = '<div class="btn-group">';

                        if (auth()->user()->can('user-view')) {
                            $return .=  '<a href="'.route('user.view', ['id' => base64_encode($data->id)]).'" class="btn btn-default btn-xs">
                                                <i class="fa fa-eye"></i>
                                            </a> &nbsp;';
                        }

                        // if (auth()->user()->can('user-edit')) {
                        //     $return .= '<a href="'.route('user.edit', ['id' => base64_encode($data->id)]).'" class="btn btn-default btn-xs">
                        //                         <i class="fa fa-edit"></i>
                        //                     </a> &nbsp;';
                        // }

                        if (auth()->user()->can('user-delete')) {
                            $return .= '<a href="javascript:;" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown">
                                                <i class="fa fa-bars"></i>
                                            </a> &nbsp;
                                            <ul class="dropdown-menu">
                                                
                                                <li><a class="dropdown-item" href="javascript:;" onclick="Permenant_delete(this);" data-status="deleted" data-id="' . base64_encode($data->id) . '">Permenant Delete</a></li>
                                            </ul>';
                        }

                        $return .= '</div>';

                        return $return;
                    })

                    ->editColumn('status', function ($data) {
                        
                        if ($data->status == 'active') {
                            return '<span class="badge badge-pill badge-success">Active</span>';
                        } else if ($data->status == 'inactive') {
                            return '<span class="badge badge-pill badge-warning">Inactive</span>';
                        } else if ($data->status == 'deleted') {
                            return '<span class="badge badge-pill badge-danger">Deleted</span>';
                        } else {
                            return '-';
                        }
                    })

                    ->editColumn('name', function ($data) {
                        
                            return $data->first_name.' '.$data->last_name;
                        
                    })

                    ->editColumn('role', function ($data) {
                        if(!empty($data->roles->first()->name)){
                            return ucfirst(str_replace('_', ' ', $data->roles->first()->name));
                        }else{
                            return null;
                        }
                        
                    })
                    
                    ->editColumn('department', function ($data) {
                        $department = Department::where(['id' => $data->department_id])->first();
                        if(!empty($department)){
                            return $department['name'];
                        }else{
                            return '';
                        }
                        
                        
                    })

                    ->rawColumns(['name', 'role', 'action', 'status'])
                    ->make(true);
            }
            
            return view('user.trash');
        }
    /** Trash */

    /** create */
        public function create(Request $request){
            $roles = Role::all();
            $department = Department::all()->where('status','active');
            $branch = Branch::where(['status' => 'active'])->get();
            $team = Teammaster::where(['status' => 'active'])->get();
            return view('user.create')->with([
                'roles' => $roles,
                'branch' => $branch,
                'department' => $department,
                'team' => $team
            ]);
        }
    /** create */

    /** insert */
        public function insert(UserRequest $request){
            if ($request->ajax()) {
                return response()->json(['status' => 'success']);
            }
        
            // Default password if not provided
            $password = $request->password ?? 'Abcd@123?';
        
            // Convert branch to a string if it's an array
            $branches = !empty($request->branch) ? implode(',', $request->branch) : '';
        
            // Format joining_date
            $formattedDate = $request->joining_date ? date("Y-m-d", strtotime($request->joining_date)) : null;
        
            $role = $request->role;
            if($role == '49'){
                $flag = 0;
            } elseif($role == '20') {
                $flag = 1;
            } elseif($role == '26') {
                $flag = 2;
            } else if($role == '25') {
                $flag = 3;
            } else if($role == '24') {
                $flag = 4;
            } else {
                $flag = '';
            } 
            $data = [
                'first_name' => ucfirst($request->first_name),
                'last_name' => ucfirst($request->last_name),
                'email' => $request->email,
                'contact_number' => $request->contact_number,
                'branch' => $branches,
                'joining_date' => $formattedDate,
                'flag' => $flag, 
                'status' => 'active',
                'password' => bcrypt($password),
                'department_id' => $request->department,
                'team_name' => $request->team_name,
                'created_at' => now(),
                'created_by' => auth()->user()->id,
                'updated_at' => now(),
                'updated_by' => auth()->user()->id,
            ];
            
            DB::beginTransaction();
            try {
                $user = User::create($data);
                $user->assignRole($request->role);
        
                if ($user) {
                    DB::commit();
                    return redirect()->route('user')->with('success', 'Record inserted successfully');
                } else {
                    DB::rollback();
                    return redirect()->back()->with('error', 'Failed to insert record')->withInput();
                }
            } catch (\Throwable $th) {
                DB::rollback();
                return redirect()->back()->with('error', 'Something went wrong, please try again later')->withInput();
            }
        }
    /** insert */

    /** edit */
        public function edit(Request $request, $id = ''){
            if (!isset($id) || empty($id)) {
                return redirect()->route('user')->with('error', 'Something went wrong');
            }
            $id = base64_decode($id);
        
            $roles = Role::all();
            $department = Department::all()->where('status','active');
            $branch = Branch::where(['status' => 'active'])->get();
            $team = Teammaster::where(['status' => 'active'])->get();
            $data = User::select(
                'id', 
                'first_name', 
                'branch', 
                'last_name', 
                'email', 
                'contact_number', 
                'password', 
                'department_id', 
                'team_name', 
                'joining_date'
            )
            ->where(['id' => $id])
            ->first();
        
            if ($data) {
                return view('user.edit')->with([
                    'data' => $data,
                    'roles' => $roles,
                    'branch' => $branch,
                    'department' => $department,
                    'team' => $team,
                ]);
            } else {
                return redirect()->route('user')->with('error', 'User not found');
            }
        }
    /** edit */

    /** team_transfer */
        public function team_transfer(Request $request, $id = ''){
            if (isset($id) && $id != '' && $id != null)
                $id = base64_decode($id);
            else
                return redirect()->route('user')->with('error', 'Something went wrong');

            $team = Teammaster::where(['status' => 'active'])->get();
            $data = User::select('id','first_name', 'branch','last_name','email', 'contact_number', 'password','department_id','team_name')->where(['id' => $id])->first();
            return view('user.team_transfer')->with(['data' => $data, 'team' => $team]);
        }
    /** team_transfer */

    /** update */
        public function update(UserRequest $request){
            if ($request->ajax()) {
                return response()->json(['status' => 'success']);
            }
        
            $id = $request->id;
            $exst_rec = User::where(['id' => $id])->where('status','active')->first();
        
            if (!$exst_rec) {
                return redirect()->route('user')->with('error', 'User not found');
            }
        
            // Convert branch to a string if it's an array
            $branch = !empty($request->branch) ? implode(',', $request->branch) : '';
        
            // Format joining_date
            $joiningDate = $request->joining_date ? date('Y-m-d', strtotime($request->joining_date)) : null;
            
            $role = $request->role;
            if($role == '49'){
                $flag = 0;
            } elseif($role == '20') {
                $flag = 1;
            } elseif($role == '26') {
                $flag = 2;
            } else if($role == '25') {
                $flag = 3;
            } else if($role == '24') {
                $flag = 4;
            } else {
                $flag = NULL;
            } 
        
            // Prepare data for update
            $data = [
                'first_name' => ucfirst($request->first_name),
                'last_name' => ucfirst($request->last_name),
                'contact_number' => $request->contact_number,
                'email' => $request->email,
                'branch' => $branch,
                'joining_date' => $joiningDate,
                'flag' => $flag, 
                'department_id' => $request->department,
                'team_name' => $request->team_name,
                'updated_at' => now(),
                'updated_by' => auth()->user()->id,
            ];
        
            // Update password if provided
            if (!empty($request->password)) {
                $data['password'] = bcrypt($request->password);
            }
        
            DB::beginTransaction();
            try {
                // Update user record
                $update = User::where(['id' => $id])->update($data);
        
                if ($update) {
                    // Update roles
                    DB::table('model_has_roles')->where(['model_id' => $id])->delete();
                    $exst_rec->assignRole($request->role);
        
                    DB::commit();
                    return redirect()->route('user')->with('success', 'Record updated successfully');
                } else {
                    DB::rollback();
                    return redirect()->back()->with('error', 'Failed to update record')->withInput();
                }
            } catch (\Throwable $th) {
                DB::rollback();
                return redirect()->back()->with('error', 'Something went wrong, please try again later')->withInput();
            }
        }
    /** update */

    /** update_team_transfer */
        public function update_team_transfer(Request $request){
            if($request->ajax()) { return true; }

            $id = $request->id;
            $exst_rec = User::where(['id' => $id])->first();

            $data = [
                'team_name' => $request->team_name
            ];


                
                // DB::enableQueryLog();
                $update = User::where(['id' => $id])->update($data);
            // dd(DB::getQueryLog());
                if ($update) {
                    return redirect()->route('user')->with('success', 'Record updated successfully');
                } else {
                    DB::rollback();
                    return redirect()->back()->with('error', 'Failed to update record')->withInput();
                }
          
        }
    /** update_team_transfer */

    /** view */
        public function view(Request $request, $id = ''){
            if (isset($id) && $id != '' && $id != null)
                $id = base64_decode($id);
            else
                return redirect()->route('user')->with('error', 'Something went wrong');

            $roles = Role::all();
            $branch = Branch::where(['status' => 'active'])->get();
           
            $data = User::select( 'id', 'first_name' ,'branch' ,'last_name', 'email', 'contact_number', 'password','team_name','department_id')
                                ->where(['id' => $id])
                                ->first();

           // $team = Teammaster::where(['status' => 'active'])->get();
             $department = User::select('users.department_id', 'department.name as d_name', 'department.id as d_id')
            ->leftJoin('department','department.id','=','users.department_id')
            ->where('users.status', 'active')->get();

           $team = User::select('users.team_name', 'Team_master.team_name as t_name', 'Team_master.id as t_id')
            ->leftJoin('Team_master','Team_master.id','=','users.team_name')
            ->where('users.status', 'active')->get();
            
        return view('user.view')->with(['data' => $data, 'roles' => $roles ,'branch' => $branch,'team' => $team,'department' => $department]);
        }
    /** view */

    /** change-status */
        public function change_status(Request $request){
            if (!$request->ajax()) { exit('No direct script access allowed'); }

            if (!empty($request->all())) {
                $id = base64_decode($request->id);
                $status = $request->status;

                $data = User::where(['id' => $id])->first();

                if(!empty($data)){
                    $process = User::where(['id' => $id])->update(['status' => $status, 'updated_by' => auth()->user()->id]);
                    if($process){
                        return response()->json(['code' => 200]);
                    }else{
                        return response()->json(['code' => 201]);
                    }
                } else {
                    return response()->json(['code' => 201]);
                }
            } else {
                return response()->json(['code' => 201]);
            }
        }
    /** change-status */
    
    /** permenant-delete */
        public function Permenant_delete(Request $request){
            if (!$request->ajax()) { exit('No direct script access allowed'); }

            if (!empty($request->all())) {
                $id = base64_decode($request->id);
                $status = $request->status;

                $data = User::where(['id' => $id])->first();

                if(!empty($data)){
                    $data = User::where(['id' => $id])->delete();
                    if($process){
                        return response()->json(['code' => 200]);
                    }else{
                        return response()->json(['code' => 201]);
                    }
                } else {
                    return response()->json(['code' => 201]);
                }
            } else {
                return response()->json(['code' => 201]);
            }
        }
    /** permenant-delete */

    /** remove-profile */
        public function profile_remove(Request $request){
            if(!$request->ajax()) { exit('No direct script access allowed'); }

            if(!empty($request->all())){
                $id = base64_decode($request->id);
                $data = User::find($id);

                if($data){
                    if($data->photo != ''){
                        $file_path = public_path().'/uploads/users/'.$data->photo;

                        if(File::exists($file_path) && $file_path != ''){
                            if($data->photo != 'user-icon.jpg') {
                                @unlink($file_path);
                            }
                        }

                        $update = User::where(['id' => $id])->update(['photo' => '']);

                        if($update)
                            return response()->json(['code' => 200]);
                        else
                            return response()->json(['code' => 201]);
                    }else{
                        return response()->json(['code' => 200]);
                    }
                }else{
                    return response()->json(['code' => 201]);
                }
            }else{
                return response()->json(['code' => 201]);
            }
        }
    /** remove-profile */
    
    /** Import */
        public function import(Request $request){

            if(Excel::import(new ImportUser, $request->file('file')->store('file'))){
                return redirect()->route('user')->with('sucess' ,'File Imported Sucessfully');
            }else{
                return redirect()->route('user')->with('error' ,'Faild To Import File!');
            }
        }
    /** Import */
    
    /** Export */
        public function export(Request $request){
            if(isset($request->slug) && $request->slug != null){
                $slug = $request->slug;
            }else{
                $slug = 'all';
            }

            $name = 'Users_'.Date('YmdHis').'.xlsx';

            try {
                return Excel::download(new ExportUser($slug), $name);
            }catch(\Exception $e){
                return redirect()->back()->with('error' ,$e->getMessage());
            }
        }
    /** Export */
    
    
    
    public function change_password_form(Request $request)
    {
        return view('user.change_password');        
    }
    
    public function change_password_save(Request $request)
    {
        $user = auth()->user();
        
             $user->password = bcrypt($request->input('new_password'));
            $user->save();
            return redirect()->route('dashboard');
    
    }
    
    public function change_password_user_save(Request $request)
    {
        // Validate the request data
        $request->validate([
            'email' => 'required|email',
            'new_password' => 'required|min:8',
        ]);
    
        // Check if the user exists
        $user = User::where('email', $request->input('email'))->first();
        if (!$user) {
            return redirect()->back()->with('error', 'User not found.');
        }
    
        // Update the user's password
        $user->password = bcrypt($request->input('new_password'));
        $user->save();
    
        return redirect()->route('login')->with('success', 'Password changed successfully. Please login with your new password.');
    }
    
    public function change_password_form_user(Request $request)
    {
        return view('user.change_password_user');        
    }
    
    public function getDepartmentWiseData()
    {
        $departmentCounts = DB::table('department')
            ->select('name', DB::raw('COUNT(*) as count'))
            ->groupBy('name')
            ->get();
    
        $data = [
            'labels' => $departmentCounts->pluck('name'), 
            'counts' => $departmentCounts->pluck('count')          
        ];
    
        return response()->json($data);
    }

}
