<?php

namespace App\Http\Controllers;

use App\Models\Department;
use App\Models\User;
use App\Services\VisibilityService;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class VisibilityManagerController extends Controller
{
    /** @var VisibilityService */
    private $visibility;

    public function __construct(VisibilityService $visibility)
    {
        $this->visibility = $visibility;
    }

    public function index(Request $request)
    {
        $departments = Department::withCount('users')->orderBy('name')->get();
        $users = User::with(['department', 'roleRecord'])
            ->whereHas('roleRecord', function ($q) {
                $q->where('is_platform_admin', false);
            })
            ->orderBy('name')
            ->get();
        $modulesGrouped = $this->visibility->modulesGrouped();

        $selectedDepartment = null;
        $departmentPermissions = [];
        if ($request->filled('department_id')) {
            $selectedDepartment = Department::find($request->department_id);
            if ($selectedDepartment) {
                $departmentPermissions = $this->visibility->departmentPermissionsMap($selectedDepartment->id);
            }
        }

        $selectedUser = null;
        $userOverrideStates = [];
        $userEffectivePermissions = [];
        if ($request->filled('user_id')) {
            $selectedUser = User::with('department')->find($request->user_id);
            if ($selectedUser && $selectedUser->roleRecord && !$selectedUser->isPlatformAdmin()) {
                $userOverrideStates = $this->visibility->userOverrideStates(
                    $selectedUser->id,
                    (int) $selectedUser->department_id
                );
                $userEffectivePermissions = $this->visibility->resolvedPermissionsForUser($selectedUser);
            }
        }

        return view('visibility.index', compact(
            'departments',
            'users',
            'modulesGrouped',
            'selectedDepartment',
            'departmentPermissions',
            'selectedUser',
            'userOverrideStates',
            'userEffectivePermissions'
        ));
    }

    public function storeDepartment(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:120',
            'description' => 'nullable|string|max:255',
        ]);

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

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

        $this->visibility->syncDepartmentPermissions($department->id, []);

        return redirect()
            ->route('visibility.index', ['department_id' => $department->id])
            ->with('success', 'Department created. Configure module access below.');
    }

    public function updateDepartmentPermissions(Request $request, Department $department)
    {
        $allowed = $request->input('modules', []);
        if (!is_array($allowed)) {
            $allowed = [];
        }
        $allowed = array_values(array_intersect($allowed, $this->visibility->moduleKeys()));

        $this->visibility->syncDepartmentPermissions($department->id, $allowed);

        return redirect()
            ->route('visibility.index', ['department_id' => $department->id])
            ->with('success', 'Department visibility updated.');
    }

    public function updateUserOverrides(Request $request, User $user)
    {
        if ($user->isPlatformAdmin()) {
            return redirect()->route('visibility.index')->withErrors(['user_id' => 'Cannot override platform admin users.']);
        }

        $states = [];
        foreach ($this->visibility->moduleKeys() as $key) {
            $states[$key] = $request->input('override.' . $key, 'inherit');
            if (!in_array($states[$key], ['inherit', 'allow', 'deny'], true)) {
                $states[$key] = 'inherit';
            }
        }

        $this->visibility->syncUserOverrides($user->id, $states);

        return redirect()
            ->route('visibility.index', ['user_id' => $user->id])
            ->with('success', 'User visibility overrides saved.');
    }
}
