<?php

namespace App\Http\Controllers;

use App\DataTables\UserDailyAttendanceDataTable;
use App\DataTables\UserDataTable;
use App\DataTables\WorkSessionDataTable;
use App\DataTables\WorkSessionReportDataTable;
use App\Exports\UserSessionExport;
use App\Models\Governorate;
use App\Models\Role;
use App\Models\User;
use App\Models\UserWorkSession;
use Defuse\Crypto\Crypto;
use Defuse\Crypto\Key;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Maatwebsite\Excel\Facades\Excel;

class UserController extends Controller
{
    public function index(UserDataTable $dataTable)
    {
        $user = auth()->guard('admin')->user();
        if($user->role_id == Role::SUPERVISOR_ROLE){
            $governorates = Governorate::query()->where('id', $user->gov_id)->get();
        }else{
            $governorates = Governorate::query()->get();
        }
        $employees = User::query()->whereIn('gov_id', $governorates->keyBy('id')->keys()->toArray())->get();
        return $dataTable->render('users.index', compact('governorates', 'employees'));
    }

    public function datatables(UserDataTable $dataTable)
    {
        return $dataTable->ajax();
    }

    public function add()
    {
        $roles = Role::query()->get();
        $governorates = Governorate::query()->get();
        $user = new User();
        if(old('username') != null){
            $user->username = old('username');
            $user->email = old('email');
            $user->full_name = old('full_name');
            $user->is_active = old('is_active');
        }
        return view('users.add', compact('roles', 'user', 'governorates'));
    }

    public function create(Request $request)
    {
        $username = strtolower($request->username);
        //check if user exist
        $userExist = User::query()->where('username', $username)->count();

        if($userExist > 0){
            return redirect()->back()->withErrors(__('Username already exist'))->withInput();
        }
        // Load the encryption key from the User model
        $key = Key::loadFromAsciiSafeString(User::ENCRYPTION_KEY);
        // Encrypt the user's first name and last name
        $encryptedFullName = Crypto::encrypt($request->full_name, $key);
        $encryptedEmail = $request->email != null ? Crypto::encrypt($request->email ?? '', $key):"";
        $user = User::query()->insertGetId([
            "username" => $username,
            "full_name" => $encryptedFullName,
            "email" => $encryptedEmail,
            "password" => Hash::make($request->password),
            "role_id" => Role::EMPLOYEE_ROLE,
            "gov_id" => $request->gov_id,
            "is_active" => $request->is_active == 1 ? 1:0,
            "created_at" => date('Y-m-d H:i:s')
        ]);
        if($user != null){
            return redirect()->back()->with(['success' => __("User added successfully") ]);
        }else{
            return redirect()->back()->withErrors(['message' => __("Error")]);
        }
    }

    public function view(User $user, WorkSessionDataTable $dataTable)
    {
        return $dataTable->with([
            'user' => $user
        ])->render('users.view', compact('user'));
    }

    public function viewSession(UserWorkSession $session)
    {
        $user = $session->user;
        $startLocation = explode(',', $session->start_location ?? '0,0');
        $endLocation = explode(',', $session->end_location ?? '0,0');
        return view('users.view-session', compact( 'session', 'user', 'startLocation', 'endLocation'));
    }

    public function sessionsIndex(WorkSessionDataTable $dataTable)
    {
        $user = auth()->guard('admin')->user();
        if($user->role_id == Role::SUPERVISOR_ROLE){
            $governorates = Governorate::query()->where('id', $user->gov_id)->get();
        }else{
            $governorates = Governorate::query()->get();
        }
        $employees = User::query()->whereIn('gov_id', $governorates->keyBy('id')->keys()->toArray())->get();

        return $dataTable->render('users.session-index', compact('governorates', 'employees'));
    }

    public function edit(User $user)
    {
        $loggedUser = auth()->guard('admin')->user();
        if($loggedUser->role_id == Role::SUPERVISOR_ROLE){
            if(Role::checkUserRoleGovPermission($loggedUser->gov_id)){
                return abort(404);
            }
        }
        $roles = Role::query()->get();
        $governorates = Governorate::query()->get();
        if(old('username') != null){
            $user->username = old('username');
            $user->email = old('email');
            $user->full_name = old('full_name');
            $user->is_active = old('is_active');
        }else{
            $key = Key::loadFromAsciiSafeString(User::ENCRYPTION_KEY);
            $user->full_name =  $user->full_name != null ? User::getDecryptedData($user->full_name):'';
            $user->email =  $user->email != null ? User::getDecryptedData($user->email):'';
        }
        return view('users.add', compact('roles', 'user', 'governorates'));
    }

    public function update(User $user, Request $request)
    {
        // Load the encryption key from the User model
        $key = Key::loadFromAsciiSafeString(User::ENCRYPTION_KEY);
        // Encrypt the user's first name and last name
        $encryptedFullName = $request->full_name != null ? Crypto::encrypt($request->full_name, $key):"";
        $encryptedEmail = $request->email != null ? Crypto::encrypt($request->email, $key):"";

        $user->full_name = $encryptedFullName;
        $user->email = $encryptedEmail;
        if($user->password != $request->password){
            $user->password = Hash::make($request->password);
        }
        $user->role_id = $request->role_id;
        $user->gov_id = $request->gov_id;
        if($request->is_active == 1)
            $user->is_active = 1;
        else
            $user->is_active = 0;
        $user->save();
        if($user->save()){
            return redirect()->back()->with(['success' => __("User updated successfully") ]);
        }else{
            return redirect()->back()->withErrors(['message' => __("Error")]);
        }
    }

    public function dailyReport(UserDailyAttendanceDataTable $dataTable)
    {
        $user = auth()->guard('admin')->user();
        $gov_id = request()->get('gov_id');
        $start_date = request()->get('start_date') != null ? request()->get('start_date'):date('Y-m-d');
//        $start_date = request()->get('start_date') != null ? request()->get('start_date'):'2024-01-24';
        $employee = request()->get('employee');
        if($user->role_id == Role::SUPERVISOR_ROLE){
            $governorates = Governorate::query()->where('id', $user->gov_id)->get();
        }else{
            $governorates = Governorate::query()->get();
        }
        $employees = User::query()->whereIn('gov_id', $governorates->keyBy('id')->keys()->toArray())->get();
        $sessions = UserWorkSession::query();
        if($start_date != null){
            $sessions = $sessions->whereDate('start_date', $start_date);
        }
        if($employee != null){
            $sessions = $sessions->whereIn('user_id', $employee);
        }else{
            $sessions = $sessions->whereIn('user_id', $employees->pluck('id')->toArray());
        }
        if($gov_id != null){
            $sessions = $sessions->whereIn('user_id', function($q) use($gov_id) {
                $q->select('id')->from((new User())->getTable())->where('gov_id', $gov_id)->get();
            });
        }else{
            $sessions = $sessions->whereIn('user_id', function($q) use($governorates) {
                $q->select('id')->from((new User())->getTable())->whereIn('gov_id', $governorates->pluck('id')->toArray())->get();
            });
        }
        $sessions = $sessions->get()->keyBy('user_id');

        return $dataTable->with('sessions', $sessions)->render('users.session-report', compact('governorates', 'employees', 'sessions'));
    }

    public function attendanceReport(WorkSessionDataTable $dataTable)
    {
        $user = auth()->guard('admin')->user();
        if($user->role_id == Role::SUPERVISOR_ROLE){
            $governorates = Governorate::query()->where('id', $user->gov_id)->get();
        }else{
            $governorates = Governorate::query()->get();
        }
        $employees = User::query()->whereIn('gov_id', $governorates->keyBy('id')->keys()->toArray())->get();

        return $dataTable->render('users.session-report', compact('governorates', 'employees'));
    }

    public function delete(User $user)
    {
        //uses soft delete
        try{
            $user->delete();
            return response()->json(['success' => true, 'message' => 'User Deleted Successfully']);
        }catch (\Exception $exception){
            return response()->json(['success' => false, 'message' => $exception->getMessage()]);
        }
    }

    public function exportDailySessions(Request $request)
    {
        if($request->employee != null)
            $userId = explode(',', $request->employee);
        else
            $userId = null;
        $govId  = $request->gov_id;
        $dates = [];
        if($request->start_date != null)
            $dates['start_date'] = $request->start_date;
        if($request->end_date != null)
            $dates['end_date'] = $request->end_date;
//        $dates = ['start_date' => $request->start_date, 'end_date' => $request->end_date];
        $fileName = 'Attendance-Report- ';
        if($request->start_date != null){
            $fileName .= $request->start_date;
        }
        if($request->user_id != null){
            $fileName .= '_'.$request->user_id.'_';
        }
        $fileName .= ' '. date("Y-m-d His") .'.xlsx';
        return Excel::download(new UserSessionExport($userId, $govId, $dates), $fileName);
    }
}
