<?php

namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use Inertia\Inertia;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Spatie\Permission\Models\Role;
use Illuminate\Http\JsonResponse;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;
use DB;
use App\Traits\DeleteModelTrait;  

class ProfileController extends Controller
{
    use DeleteModelTrait;
    public function updateProfile(Request $request)
    {
        $user = Auth::user(); // Get the currently authenticated user

        try{
            DB::beginTransaction();
            // Validate the input fields
            $request->validate([
                'name' => 'required|string|max:255',
                'email' => 'required|email|max:255|unique:users,email,' . $user->id, // Ensure unique email
                'old_password' => 'required|string',
                'password' => 'nullable|string|min:8|confirmed',
            ]);

            // Check if the provided old password matches the user's current password using bcrypt
            if (!password_verify($request->old_password, $user->password)) {
                throw ValidationException::withMessages([
                    'old_password' => 'Incorrect password, Enter your valid current password.'
                ]);
            }
            //check unique password
            if ($request->filled('password')) {
                if (password_verify($request->password, $user->password)) {
                    throw ValidationException::withMessages([
                        'password' => 'New password cannot be the same as your old password.'
                    ]);
                }
            }

            if ($request->has('photo') && $request->input('photo') !== $user->photo) {
                $user->photo = $request->input('photo');
            }

            // Update the user's name and email
            $user->name = $request->name;
            $user->email = $request->email;

            // If a new password is provided, hash it with bcrypt before saving
            if ($request->filled('password')) {
                $user->password = bcrypt($request->password);
            }

            // Save the updated user data
            $user->save();
            DB::commit();
            return redirect()->back()->with('success', [
                'message' => 'Profile updated successfully',
                'check'   => false
            ]);

        }catch (ValidationException $e) {
            DB::rollBack();
            return redirect()->back()
                ->withErrors($e->errors()) 
                ->withInput(); 
        } catch (\Exception $e) {
            DB::rollBack();
            return redirect()->back()->with('error', [
                'message' => 'An error occurred:' . $e->getMessage(),
                'check'   => false
            ]);
        }
    }


    public function getProfile()
    {
        // Get the currently authenticated user
        $user = Auth::user();
        return Inertia::render('users/EditProfile', [
            'user' => $user->only('name', 'id','email', 'photo')
        ]);
    }

    public function getRoles()
    {
        $roles = Role::all();
        return response()->json($roles);
    }

    public function fetchUsers()
    {
        $users = User::orderBy('created_at', 'desc')->get();

        return Inertia::render('users/User', [
            'users' => $users->map(function ($user) {
                return [
                    'id' => $user->id,
                    'name' => $user->name,
                    'email' => $user->email,
                    'role' => $user->getRoleNames()->first(), 
                    'photo' => $user->photo,
                    'status' => $user->status,
                    'created_at' => $user->created_at,
                ];
            }),
        ]);
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit($id)
    {
        $user = User::findOrFail($id);
        $userData = $user->toArray();
        $userData['role'] = $user->roles->first() ? $user->roles->first()->id : '';
        
        return response()->json($userData);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, $id)
    {
        try {
            DB::beginTransaction();

            $validatedData = $request->validate([
                'name' => 'required|string|max:255',
                'password' => 'nullable|string|min:8|confirmed',
                'role' => 'required|exists:roles,id',
                'status' => 'required|boolean',
                'photo' => 'nullable|string'
            ]);

            // Retrieve the user or fail
            $user = User::findOrFail($id);

            // Update user data (excluding password if not changed)
            $user->fill([
                'name' => $validatedData['name'],
                'status' => $validatedData['status'],
            ]);

            // Update password if provided
            if ($request->filled('password')) {
                $user->password = Hash::make($validatedData['password']);
            }

            // Update photo if changed
            if ($request->has('photo') && $request->input('photo') !== $user->photo) {
                $user->photo = $request->input('photo');
            }

            if ($request->has('email') && $request->input('email') !== $user->email) {
                $user->email = $request->input('email');
            }


            // Save changes if any
            if ($user->isDirty()) {
                $user->save();
            }

            // **Update role using Spatie's syncRoles()**
            $role = Role::findById($validatedData['role']); // Ensure role exists
            $user->syncRoles([$role]);

            DB::commit();

            return Redirect::back()->with('success', [
                'message' => 'User updated successfully',
                'check'   => false
            ]);
        } catch (ValidationException $e) {
            DB::rollBack();
            return Redirect::back()->with('error', [
                'message' => 'Validation error: ' . $e->getMessage(),
                'check'   => $e->getMessage()
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return Redirect::back()->with('error', [
                'message' => 'Error: ' . $e->getMessage(),
                'check'   => $e->getMessage()
            ]);
        }
    }


    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:8|confirmed',
            'role' => 'required|exists:roles,id',
            'status' => 'required|boolean',
            'photo' => 'nullable|string'
        ]);

        try {
            $user = User::create([
                'name' => $request->name,
                'email' => $request->email,
                'password' => Hash::make($request->password),
                'status' => $request->status,
                'photo' => $request->photo
            ]);

            $role = Role::findById($request->role);
            $user->assignRole($role);

            return redirect()->route('admin.users')->with('success', [
                'message' => 'User created successfully',
                'check' => false
            ]);

        } catch (\Exception $e) {
            return Redirect::back()->with('error', [
                'message' => 'Failed to create user',
                'check' => $e->getMessage()
            ]);
        }
    }
    public function uploadImage(Request $request)
    {
        // Validate the image upload
        $request->validate([
            'file' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:5048',
        ]);

        $path = $request->file('file')->store('profile-images', 'public');  
        $filename = basename($path); 

        return response()->json(['filename' => 'profile-images/' . $filename]); 
    }

    public function destroy($id)
    {
        return $this->deleteModel($id, new User());
    }

}
