<?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,
            'module_is_enabled' => $node->module === null || (bool) $node->module->is_enabled,
            '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);
        }
    }
}
