<?php

declare(strict_types=1);

namespace Maestro\Core\Http\Controllers\Superadmin;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Maestro\Core\Http\Controllers\Controller;
use Maestro\Core\Models\NavigationNode;
use Maestro\Core\Services\NavigationTreeSyncService;

class SuperadminNavigationController extends Controller
{
    public function __construct(
        private readonly NavigationTreeSyncService $navigationTreeSyncService
    ) {}

    public function show(): JsonResponse
    {
        $root = NavigationNode::query()
            ->whereNull('parent_id')
            ->where('key', 'root')
            ->first();

        if ($root === null) {
            return response()->json(['tree' => []]);
        }

        $this->loadTreeRecursive($root);

        return response()->json(['tree' => [$this->serializeNode($root)]]);
    }

    public function update(Request $request): JsonResponse
    {
        $payload = $request->validate([
            'tree' => ['required', 'array', 'size:1'],
        ]);

        /** @var array<int, mixed> $tree */
        $tree = $payload['tree'];
        $this->navigationTreeSyncService->sync($tree);

        return $this->show();
    }

    /**
     * @return array<string, mixed>
     */
    private function serializeNode(NavigationNode $node): array
    {
        return [
            'key' => $node->key,
            'label' => $node->label,
            'route' => $node->route,
            'icon' => $node->icon,
            'permission' => $node->permission,
            'description' => $node->description,
            'is_header' => $node->is_header,
            'pinned_bottom' => $node->pinned_bottom,
            'module_slug' => $node->module?->slug,
            'children' => $node->children->map(fn (NavigationNode $c) => $this->serializeNode($c))->values()->all(),
        ];
    }

    private function loadTreeRecursive(NavigationNode $node): void
    {
        $node->load([
            'module',
            'children' => fn ($q) => $q->orderBy('sort_order'),
        ]);

        foreach ($node->children as $child) {
            $this->loadTreeRecursive($child);
        }
    }
}
