<?php

namespace App\Components\Admin\Users;

use App\Models\User\Role;
use App\Models\User\User;
use App\Services\HistoryService;
use Livewire\Component;

class UserEdit extends Component
{
    public User $user;

    public string $name_first;
    public string $name_last;
    public string $email;
    public string $username;
    public ?string $password = null;
    public array $roles = [];

    /** Workspaces this user is allowed to access. Empty = all allowed (null stored). */
    public array $allowedWorkspaces = [];

    /** When true, the allowed_workspaces column is set to null (unrestricted). */
    public bool $allWorkspaces = true;

    public const WORKSPACES = ['ha', 'cpf', 'wills'];

    public function mount(User $user)
    {
        $this->authorize('edit', $user);

        $this->fill([
            'name_first' => $user->name_first,
            'name_last'  => $user->name_last,
            'email'      => $user->email_address,
            'username'   => $user->username,
            'roles'      => $user->roles->pluck('name')->toArray(),
        ]);

        if ($user->allowed_workspaces === null) {
            $this->allWorkspaces      = true;
            $this->allowedWorkspaces  = [];
        } else {
            $this->allWorkspaces      = false;
            $this->allowedWorkspaces  = $user->allowed_workspaces;
        }
    }

    public function save(HistoryService $history)
    {
        $this->authorize('edit', $this->user);

        $rolesBefore = $this->user->roles->pluck('name')->sort()->values()->toArray();

        $attributes = [
            'name_first'         => $this->name_first,
            'name_last'          => $this->name_last,
            'email_address'      => $this->email,
            'username'           => $this->username,
            'allowed_workspaces' => $this->allWorkspaces
                ? null
                : array_values(array_intersect($this->allowedWorkspaces, self::WORKSPACES)),
        ];
        $before = $this->user->only(array_keys($attributes));

        $this->user->update($attributes);

        $changed = [];
        foreach ($this->user->getChanges() as $field => $newValue) {
            if (in_array($field, ['updated_at', 'created_at'])) {
                continue;
            }
            $changed[$field] = ['from' => $before[$field] ?? null, 'to' => $newValue];
        }

        $passwordReset = false;
        if ($this->password) {
            $this->user->update([
                'password' => bcrypt($this->password),
            ]);
            $passwordReset = true;
        }

        $this->user->syncRoles($this->roles);
        $rolesAfter = $this->user->roles->pluck('name')->sort()->values()->toArray();

        $context = ['changed' => $changed];
        if ($passwordReset) {
            $context['password_reset'] = true;
        }
        if ($rolesBefore !== $rolesAfter) {
            $context['roles'] = ['from' => $rolesBefore, 'to' => $rolesAfter];
        }

        $history->add($this->user, 'User account updated', $context);

        $this->dispatch('toast',
            title: 'Saved',
            message: 'Successfully saved data.',
            type: 'success'
        );
    }

    public function render() {
        return view('components.admin.users.user-edit', [
            'allRoles' => Role::orderBy('name')->get(),
        ]);
    }
}
