<?php

namespace App\Modules\Settings\Rbac\Controllers;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Modules\Admin\Tenancy\Models\Tenant;
use App\Modules\Settings\Rbac\DTOs\TenantUserWriteData;
use App\Modules\Settings\Rbac\Requests\ResetTenantUserPasswordRequest;
use App\Modules\Settings\Rbac\Requests\UpdateTenantUserRequest;
use App\Modules\Settings\Rbac\Services\TenantRoleManagementService;
use App\Modules\Settings\Rbac\Services\TenantUserDirectoryService;
use App\Modules\Settings\Rbac\Services\TenantUserManagementService;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;

class TenantUserEditController extends Controller
{
    public function __construct(
        private readonly TenantUserDirectoryService $directory,
        private readonly TenantUserManagementService $management,
        private readonly TenantRoleManagementService $roles,
    ) {}

    public function edit(int $user): View
    {
        [$tenant, $target] = $this->context($user);

        return view('pages.settings.users.edit', [
            'targetUser' => $target,
            'roles' => $this->roles->listAssignable($tenant),
            'assignedRoleIds' => $target->roles->pluck('id')->all(),
            'employeeOptions' => $this->directory->employeeOptionsForTenant($tenant),
        ]);
    }

    public function update(UpdateTenantUserRequest $request, int $user): RedirectResponse
    {
        [$tenant, $target] = $this->context($user);
        $this->management->update(
            $tenant,
            $target,
            TenantUserWriteData::fromValidated($request->validated()),
        );

        return $this->redirect($user, __('rbac.flash.user_updated'));
    }

    public function resetPassword(
        ResetTenantUserPasswordRequest $request,
        int $user,
    ): RedirectResponse {
        [$tenant, $target] = $this->context($user);
        $this->management->resetPassword(
            $tenant,
            $target,
            $request->user(),
            (string) $request->validated('password'),
        );

        return $this->redirect($user, __('rbac.flash.password_reset'));
    }

    public function deactivate(int $user): RedirectResponse
    {
        [$tenant, $target] = $this->context($user);
        $actor = auth()->user();
        abort_unless($actor instanceof User, 403);
        $this->management->deactivate($tenant, $target, $actor);

        return $this->redirect($user, __('rbac.flash.user_deactivated'));
    }

    public function activate(int $user): RedirectResponse
    {
        [$tenant, $target] = $this->context($user);
        $this->management->activate($tenant, $target);

        return $this->redirect($user, __('rbac.flash.user_activated'));
    }

    /**
     * @return array{Tenant, User}
     */
    private function context(int $user): array
    {
        $tenant = auth()->user()?->tenant;
        abort_if($tenant === null, 403);
        $target = $this->directory->findTenantUser($tenant, $user);
        abort_if($target === null, 404);

        return [$tenant, $target];
    }

    private function redirect(int $user, string $status): RedirectResponse
    {
        return redirect()
            ->route('settings.users.edit', $user)
            ->with('status', $status);
    }
}
