<?php

namespace App\Http\Controllers;

use App\Models\Department;
use App\Models\Role;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Http\Request;

class UserManagementController extends Controller
{
    public function index()
    {
        $users = User::with(['department', 'roleRecord'])->orderBy('name')->get();
        $departments = Department::where('is_active', true)->orderBy('name')->get();
        $roles = Role::where('is_active', true)->orderBy('name')->get();

        return view('users.index', compact('users', 'departments', 'roles'));
    }

    public function store(Request $request)
    {
        $validated = $this->validatedUser($request);

        User::create([
            'name' => $validated['name'],
            'email' => $validated['email'],
            'password' => Hash::make($validated['password']),
            'role_id' => $validated['role_id'],
            'department_id' => $validated['department_id'],
        ]);

        return redirect()->back()->with('success', 'User created.');
    }

    public function edit(User $user)
    {
        $user->load(['department', 'roleRecord']);
        $departments = Department::query()
            ->where(function ($q) use ($user) {
                $q->where('is_active', true);
                if ($user->department_id) {
                    $q->orWhere('id', $user->department_id);
                }
            })
            ->orderBy('name')
            ->get();
        $roles = Role::where('is_active', true)->orderBy('name')->get();

        return view('users.edit', compact('user', 'departments', 'roles'));
    }

    public function update(Request $request, User $user)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email|max:255|unique:users,email,' . $user->id,
            'role_id' => 'required|exists:roles,id',
            'department_id' => 'nullable|exists:departments,id',
            'password' => 'nullable|string|min:6|confirmed',
        ]);

        $role = Role::findOrFail($validated['role_id']);
        $validated['department_id'] = $role->is_platform_admin ? null : ($validated['department_id'] ?: null);

        $user->name = $validated['name'];
        $user->email = $validated['email'];
        $user->role_id = $validated['role_id'];
        $user->department_id = $validated['department_id'];

        if (!empty($validated['password'])) {
            $user->password = Hash::make($validated['password']);
        }

        $user->save();

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

    public function destroy(User $user)
    {
        if ($user->id === auth()->id()) {
            return redirect()->route('users.index')->withErrors(['delete' => 'You cannot delete your own account.']);
        }

        $user->delete();

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

    public function storeDepartmentQuick(Request $request)
    {
        $validated = $request->validate([
            'department_name' => 'required|string|max:120',
        ]);

        $slug = \Illuminate\Support\Str::slug($validated['department_name']);
        $base = $slug;
        $i = 1;
        while (Department::where('slug', $slug)->exists()) {
            $slug = $base . '-' . $i;
            $i++;
        }

        $department = Department::create([
            'name' => $validated['department_name'],
            'slug' => $slug,
            'is_active' => true,
        ]);

        app(\App\Services\VisibilityService::class)->syncDepartmentPermissions($department->id, []);

        return redirect()->route('users.index')->with('success', 'Department "' . $department->name . '" added. You can assign it to users below.');
    }

    private function validatedUser(Request $request): array
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email|max:255|unique:users,email',
            'password' => 'required|string|min:6|confirmed',
            'role_id' => 'required|exists:roles,id',
            'department_id' => 'nullable|exists:departments,id',
        ]);

        $role = Role::findOrFail($validated['role_id']);
        if ($role->is_platform_admin) {
            $validated['department_id'] = null;
        }

        return $validated;
    }
}
