<?php

namespace App\Http\Controllers;

use App\Models\User;
use Spatie\Permission\Models\Role;
use App\Models\Store;
use App\Models\UserStore;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Auth;

class UsersController extends Controller
{
    private function variables($variables = array())
    {
        if ($this->logged_role_id == 1 && isset($variables['judul']) and strpos((string)$variables['judul'], 'View') === false) {
            // Jika administrator, ambil semua store yang belum dihapus
            $variables['stores'] = Store::where('delete_flag', 0)->orderBy('name')->get();
        } else {
            // Jika bukan administrator, ambil store berdasarkan tabel UsersStore
            $variables['stores'] = UserStore::with('store') // pastikan relasi `store` didefinisikan
                ->where('user_id', $this->logged_user_id)
                ->get()
                ->pluck('store') // ambil hanya object Store
                ->sortBy('name') // urutkan berdasarkan nama
                ->values(); // reset index
        }

        $variables['header_routes'] = ' 
								<li class="breadcrumb-item">Master</li>
								<li class="breadcrumb-item">User</li>  
								<li class="breadcrumb-item active">User</li>
							 ';
        return $variables;
    }

    public function index(Request $request)
    {
        if ($request->ajax()) {
            $query = User::with('roles')->where('delete_flag', 0);

            if ($request->has('search') && $request->search['value'] != '') {
                $search = $request->search['value'];
                $query->where(function ($q) use ($search) {
                    $q->where('username', 'ilike', "%{$search}%")
                        ->orWhere('fullname', 'ilike', "%{$search}%")
                        ->orWhere('email', 'ilike', "%{$search}%");
                });
            }

            $total = $query->count();
            $columns = ['id', 'username', 'fullname', 'email', 'created_at'];
            $orderColumn = $columns[$request->order[0]['column']] ?? 'created_at';
            $orderDir = $request->order[0]['dir'] ?? 'desc';

            $query->orderBy($orderColumn, $orderDir);

            $start = $request->start;
            $length = $request->length;
            $data = $query->skip($start)->take($length)->get();

            $result = [];
            $no = $start + 1;
            foreach ($data as $row) {
                $statusBadge = $row->status == 'Active' ? 'badge-success' : 'badge-danger';
                
                // Get user roles
                $roles = $row->roles->pluck('name')->toArray();
                $rolesDisplay = !empty($roles) 
                    ? '<span class="badge badge-info">' . implode('</span> <span class="badge badge-info">', $roles) . '</span>'
                    : '<span class="badge badge-secondary">No Role</span>';
                
                $result[] = [
                    $no++,
                    '<a href="' . route('users.show', $row->id) . '">' . $row->username . '</a>',
                    $row->fullname,
                    $row->email,
                    $rolesDisplay,
                    '<span class="badge ' . $statusBadge . '">' . ($row->status == 'Active' ? 'Aktif' : 'Nonaktif') . '</span>',
                    $row->created_at->format('M jS Y, H:i')
                ];
            }

            return response()->json([
                "draw" => intval($request->draw),
                "recordsTotal" => $total,
                "recordsFiltered" => $total,
                "data" => $result,
            ]);
        }

        return view('users.index', [
            'variables' => $this->variables()
        ]);
    }

    public function create()
    {
        $variables['judul'] = 'Add User';
        $variables['type'] = 'add';
        $variables['roles'] = Role::latest()->get();
        $variables['currentRole'] = 0;
        $variables['user_stores'] = array();
        return view('users.form', [
            'data' => json_decode(json_encode(['id' => 0])),
            'variables' => $this->variables($variables)
        ]);
    }

    public function edit(User $user)
    {
        $variables['judul'] = 'Edit User';
        $variables['type'] = 'edit';
        $variables['roles'] = Role::latest()->get();
        $variables['currentRole'] = $user->roles->pluck('id')->first();
        $variables['user_stores'] = UserStore::where('user_id', $user->id)->pluck('store_id')->toArray();

        return view('users.form', [
            'data' => $user,
            'variables' => $this->variables($variables),

        ]);
    }

    public function store(Request $request, $prm_id, $prm_type = null)
    {
        // try {
        $user = null;

        if ($prm_id) {
            $user = User::findOrFail($prm_id);
        }

        switch ($prm_type) {
            case 'cp': //change-password
                $rules = [
                    'current_password' => 'required|string|min:6',
                    'password' => 'required|string|min:6|confirmed',
                ];

                $messages = [
                    'current_password.required' => 'This field is required',
                    'current_password.min' => 'Password minimum 6 characters',
                    'password.required' => 'This field is required',
                    'password.confirmed' => 'Password confirmation does not match',
                ];

                $validateData = $request->validate($rules, $messages);

                if (!Hash::check($request->current_password, $user->password)) {
                    return back()->withErrors(['current_password' => 'The current password is incorrect.']);
                }

                $user->update([
                    'password' => $request->password,
                    'f_need_change_password' => null,
                    'updated_by' => $this->logged_user_id
                ]);

                $notif = 'aneh';
                // $notif = 'User created successfully.';
                break;

            default:
                $rules = [ 
                    'username' => $user ? 'nullable|min:6' : [
                        'required', 
                        'min:6',
                        'max:20',
                        Rule::unique('users', 'username')->ignore($user?->id),
                    ],
                    'fullname' => 'required|string|max:100',
                    'email' => [
                        'required',
                        'email',
                        'max:50',
                        Rule::unique('users', 'email')->ignore($user?->id),
                    ],
                    'password' => $user ? 'nullable|min:6' : 'required|min:6', // password wajib saat create, boleh kosong saat edit
                    'telephone' => 'nullable|string|max:16',
                    'role_id' => $prm_type == 'ema' ?  'nullable|numeric' : 'required|numeric',
                    'status' => 'required|in:Active,Inactive',
                    'flag_backdate_so' => 'nullable|boolean',
                ];

                $messages = [
                    'username.required' => 'This field is required',
                    'fullname.required' => 'This field is required',
                    'email.required' => 'This field is required',
                    'email.email' => 'Must be a valid email',
                    'email.unique' => 'Email already taken',
                    'email.max' => 'Maximum 50 characters',
                    'password.required' => 'Password is required',
                    'password.min' => 'Password minimum 6 characters',
                    'telephone' => 'Maximum 16 characters',
                    'role_id.required' => 'This field is required',
                    'status.required' => 'Status is required',
                    'status.in' => 'Status must be Active or Inactive',
                ];

                $stored = $request->validate($rules, $messages);
                
                // Handle checkbox flag_backdate_so
                $stored['flag_backdate_so'] = $request->has('flag_backdate_so');
                
                // print_r('<pre>');
                // print_r($stored);
                // exit;
                if ($user) {
                    $stored['updated_by'] = $this->logged_user_id;
                    $user->update($stored);
                    $notif = 'User updated successfully.';
                } else {
                    $stored['created_by'] = $this->logged_user_id;
                    // $stored['password'] = Hash::make($stored['password']);
                    // User::create($stored);
                    $user = User::create($stored); // <-- Tambahkan ini, simpan ke $user berguna untuk syncRoles dibelakang layar
                    $notif = 'User created successfully.';
                }

                // Update role 
                if ($prm_type == 'add' or $prm_type == 'edit') {
                    $user->syncRoles(Role::find($stored['role_id']));
                }

                if ($request->filled('user_stores')) {
                    // Update UserStore
                    UserStore::where('user_id', $user->id)->delete();
                    foreach ($request->user_stores as $storeId) {
                        UserStore::create([
                            'user_id' => $user->id,
                            'store_id' => $storeId,
                            'created_by' => $this->logged_user_id
                        ]);
                    }
                }
                break;
        }

        if ($prm_type == 'add') {
            return redirect()->route('users.index')->with('success', $notif);
        } else {
            if ($prm_type == 'cp') {
                Auth::logout();
                return redirect('login')->with('success', 'Password changed successfully, please login again!!');
            }
            return redirect()->route('users.show', $user->id)->with('success', $notif);
        }
        // } catch (\Exception $e) { //kalo pake catch malah gabisa dilempar ke kolom gitu errornya
        //     return back()->with('error', $e->getMessage()); 
        // }
    }

    public function show(User $user)
    {
        $user->load(['creator', 'modificator']);
        $variables['judul'] = 'View User ID#' . $user->id;
        return view('users.show', [
            'data' => $user,
            'variables' => $this->variables($variables),
            'role' => $user->roles->pluck('id')->first() ?? '&mdash;',
        ]);
    }

    public function destroy(User $user)
    {
        $user->update([
            'username' => $user->id . '#' . $user->username,
            'email' => $user->id . '#' . $user->email,
            'delete_flag' => 1,
            'updated_by' => $this->logged_user_id
        ]);

        return redirect()->route('users.index')
            ->with('success', 'User deleted successfully.');
    }

    public function changePassword(User $user)
    {
        $variables['judul'] = 'Change Password';
        $variables['type'] = 'cp';
        return view('users.form', [
            'data' => $user,
            'variables' => $this->variables($variables),

        ]);
    }

    public function resetPassword(User $user)
    {
        $variables['new_password'] = Str::random(6);
        $user->update([
            'f_need_change_password' => $variables['new_password'],
            'password' => $variables['new_password'],
            'updated_by' => $this->logged_user_id
        ]);
        $notif = "new password " . $variables['new_password'];
        return redirect()->route('users.show', $user->id)->with('success', $notif);
    }

    public function editMyAccount(User $user)
    {
        $variables['judul'] = 'Edit My Account';
        $variables['type'] = 'ema';
        return view('users.form', [
            'data' => $user,
            'variables' => $this->variables($variables),
        ]);
    }

    /**
     * Display session management page
     */
    public function sessionManagement(Request $request)
    {
        if ($request->ajax()) {
            $query = User::where('delete_flag', 0);

            if ($request->has('search') && $request->search['value'] != '') {
                $search = $request->search['value'];
                $query->where(function ($q) use ($search) {
                    $q->where('username', 'ilike', "%{$search}%")
                        ->orWhere('fullname', 'ilike', "%{$search}%")
                        ->orWhere('email', 'ilike', "%{$search}%");
                });
            }

            $total = $query->count();
            $columns = ['id', 'username', 'fullname', 'email', 'status', 'last_login_at'];
            $orderColumn = $columns[$request->order[0]['column']] ?? 'last_login_at';
            $orderDir = $request->order[0]['dir'] ?? 'desc';

            $query->orderBy($orderColumn, $orderDir);

            $start = $request->start;
            $length = $request->length;
            $data = $query->skip($start)->take($length)->get();

            $result = [];
            $no = $start + 1;
            foreach ($data as $row) {
                $statusBadge = $row->status == 'Active' ? 'badge-success' : 'badge-danger';
                $sessionBadge = $row->hasActiveSession() ? 'badge-success' : 'badge-secondary';
                $sessionStatus = $row->hasActiveSession() ? 'Online' : 'Offline';
                
                $lastLogin = $row->last_login_at ? $row->last_login_at->format('d M Y H:i') : '-';
                $lastLoginIp = $row->last_login_ip ?? '-';
                
                $killButton = '';
                if ($row->hasActiveSession()) {
                    $killButton = '<button class="btn btn-danger btn-xs kill-session" data-id="' . $row->id . '" data-username="' . $row->username . '" data-toggle="tooltip" title="Kill Session">
                        <i class="fas fa-power-off"></i> Kill Session
                    </button>';
                }
                
                $result[] = [
                    $no++,
                    $row->username,
                    $row->fullname,
                    '<span class="badge ' . $statusBadge . '">' . ($row->status == 'Active' ? 'Aktif' : 'Nonaktif') . '</span>',
                    '<span class="badge ' . $sessionBadge . '">' . $sessionStatus . '</span>',
                    $lastLogin,
                    $lastLoginIp,
                    $killButton
                ];
            }

            return response()->json([
                "draw" => intval($request->draw),
                "recordsTotal" => $total,
                "recordsFiltered" => $total,
                "data" => $result,
            ]);
        }

        $variables['judul'] = 'Manajemen Session User';
        $variables['header_routes'] = ' 
            <li class="breadcrumb-item">Master</li>
            <li class="breadcrumb-item">User</li>  
            <li class="breadcrumb-item active">Session Management</li>
        ';

        return view('users.session-management', [
            'variables' => $variables
        ]);
    }

    /**
     * Kill user session (admin only)
     */
    public function killSession(Request $request, $userId)
    {
        try {
            $user = User::findOrFail($userId);
            
            if (!$user->hasActiveSession()) {
                return response()->json([
                    'success' => false,
                    'message' => 'User tidak memiliki session aktif'
                ], 400);
            }
            
            $user->clearSession();
            
            \Log::info('Admin killed user session', [
                'admin_id' => auth()->id(),
                'admin_username' => auth()->user()->username,
                'target_user_id' => $user->id,
                'target_username' => $user->username
            ]);
            
            return response()->json([
                'success' => true,
                'message' => "Session user {$user->username} berhasil dihapus"
            ]);
            
        } catch (\Exception $e) {
            \Log::error('Failed to kill user session', [
                'error' => $e->getMessage(),
                'user_id' => $userId
            ]);
            
            return response()->json([
                'success' => false,
                'message' => 'Gagal menghapus session: ' . $e->getMessage()
            ], 500);
        }
    }
}

