<?php

namespace App\Http\Middleware;

use App\Models\Declaration;
use App\Models\User;
use App\Models\WorkspaceUser;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Inertia\Inertia;
use Inertia\Middleware;

class HandleInertiaRequests extends Middleware
{
    /**
     * The root template that's loaded on the first page visit.
     *
     * @see https://inertiajs.com/server-side-setup#root-template
     *
     * @var string
     */
    protected $rootView = 'app';

    /**
     * Determines the current asset version.
     *
     * @see https://inertiajs.com/asset-versioning
     */
    public function version(Request $request): ?string
    {
        return parent::version($request);
    }

    /**
     * Define the props that are shared by default.
     *
     * @see https://inertiajs.com/shared-data
     *
     * @return array<string, mixed>
     */
    public function share(Request $request): array
    {
        $user = $request->user();

        $workspaces = $user
            ? $user->workspaces()
                ->orderBy('name')
                ->get(['workspaces.id', 'workspaces.name', 'workspaces.slug'])
                ->map(fn ($w) => [
                    'id' => $w->id,
                    'name' => $w->name,
                    'slug' => $w->slug,
                ])
                ->values()
                ->all()
            : [];

        $currentWorkspaceId = $request->session()->get('current_workspace_id');
        $currentWorkspace = collect($workspaces)->firstWhere('id', $currentWorkspaceId)
            ?? ($workspaces[0] ?? null);

        if (! $currentWorkspaceId && count($workspaces) > 0) {
            $request->session()->put('current_workspace_id', $currentWorkspace['id']);
        }

        return [
            ...parent::share($request),
            'flash' => [
                'success' => $request->session()->get('success'),
                'error' => $request->session()->get('error'),
            ],
            'name' => config('app.name'),
            'auth' => [
                'user' => $user,
                'workspaces' => $workspaces,
                'currentWorkspace' => $currentWorkspace,
                'workspaceRole' => $user && $currentWorkspace
                    ? WorkspaceUser::where('user_id', $user->id)
                        ->where('workspace_id', $currentWorkspace['id'])
                        ->first()?->role?->value
                    : null,
                'workspaceSwitchUrl' => $user ? route('workspace.switch') : null,
            ],
            'sidebarOpen' => ! $request->hasCookie('sidebar_state') || $request->cookie('sidebar_state') === 'true',
            'userNotifications' => [
                'unread_count' => $user && $currentWorkspace ? Cache::remember(
                    "user:{$user->id}:workspace:{$currentWorkspace['id']}:unread_notifications",
                    60,
                    fn () => $user->unreadNotifications()
                        ->whereJsonContains('data->workspace_id', $currentWorkspace['id'])
                        ->count()
                ) : 0,
                'readUrl' => fn () => $user ? route('notifications.read', ['id' => '__ID__']) : null,
                'readAllUrl' => fn () => $user ? route('notifications.readAll') : null,
                'notificationsUrl' => fn () => $user ? route('notifications.index') : null,
                'items' => Inertia::defer(function () use ($user, $currentWorkspace) {
                    if (! $user || ! $currentWorkspace) {
                        return [];
                    }

                    try {
                        $notifications = $user->notifications()
                            ->whereJsonContains('data->workspace_id', $currentWorkspace['id'])
                            ->latest()
                            ->take(10)
                            ->get();

                        $declarationIds = $notifications->pluck('data.declaration_id')->filter()->unique()->values();
                        $senderIds = $notifications->pluck('data.sender_id')->filter()->unique()->values();

                        $declarations = Declaration::whereIn('id', $declarationIds)->pluck('title', 'id');
                        $senders = User::whereIn('id', $senderIds)->pluck('name', 'id');

                        return $notifications->map(function ($n) use ($declarations, $senders) {
                            $data = $n->data;
                            $declarationId = $data['declaration_id'] ?? null;
                            $senderId = $data['sender_id'] ?? null;

                            $declarationExists = $declarationId && isset($declarations[$declarationId]);
                            $data['declaration_title'] = $declarationExists ? $declarations[$declarationId] : null;
                            $data['sender_name'] = $senderId ? ($senders[$senderId] ?? null) : null;
                            $data['url'] = $declarationExists ? route('declarations.show', $declarationId) : null;

                            return [
                                'id' => $n->id,
                                'type' => class_basename($n->type),
                                'data' => $data,
                                'read_at' => $n->read_at?->toISOString(),
                                'created_at' => $n->created_at->diffForHumans(),
                            ];
                        })->all();
                    } catch (\Throwable) {
                        return [];
                    }
                }),
            ],
        ];
    }
}
