<?php

namespace App\Http\Controllers\Module;

use App\Contracts\InstalledModuleRepositoryContract;
use App\Enums\ModuleStatus;
use App\Http\Controllers\Controller;
use App\Models\InstalledModule;
use App\Services\Module\ModuleManager;
use App\Services\Module\ModuleUninstallService;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;
use RuntimeException;

class InstalledModuleController extends Controller
{
    public function __construct(
        private readonly InstalledModuleRepositoryContract $modules,
        private readonly ModuleUninstallService $moduleUninstallService,
        private readonly ModuleManager $moduleManager,
    ) {}

    public function index(): View
    {
        $this->authorize('viewAny', InstalledModule::class);

        $modules = $this->modules->all();

        $this->moduleManager->bootInstalled();

        $entryRoutes = $modules->mapWithKeys(function (InstalledModule $module) {
            $routeName = $this->moduleManager->resolveEntryRouteName($module->module_uuid);

            if ($routeName) {
                return [$module->id => route($routeName)];
            }

            $definition = $this->moduleManager->findByUuid($module->module_uuid);

            if ($definition && $module->status === ModuleStatus::Installed) {
                return [$module->id => url('/'.strtolower($definition->slug))];
            }

            return [$module->id => null];
        });

        return view('modules.index', [
            'modules' => $modules,
            'entryRoutes' => $entryRoutes->all(),
            'installedCount' => $modules->where('status', ModuleStatus::Installed)->count(),
            'enabledCount' => $modules->where('status', ModuleStatus::Installed)->count(),
            'disabledCount' => $modules->where('status', ModuleStatus::Disabled)->count(),
            'updatesCount' => 0,
        ]);
    }

    public function show(InstalledModule $module): View
    {
        $this->authorize('view', $module);

        $entryRouteName = $this->moduleManager->resolveEntryRouteName($module->module_uuid);
        $entryUrl = $entryRouteName ? route($entryRouteName) : null;

        return view('modules.show', compact('module', 'entryUrl'));
    }

    public function destroy(InstalledModule $module): RedirectResponse
    {
        $this->authorize('uninstall', $module);

        try {
            $this->moduleUninstallService->uninstall($module);
        } catch (RuntimeException $exception) {
            return back()->with('error', $exception->getMessage());
        }

        return redirect()
            ->route('modules.index')
            ->with('success', "'{$module->name}' has been uninstalled.");
    }
}
