<?php

namespace App\Components\Admin\Users;

use App\Models\Solicitor\Solicitor;
use App\Models\User\Role;
use App\Models\User\User;
use App\Services\HistoryService;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Component;

class UserEdit extends Component
{
    use AuthorizesRequests;

    public User $user;

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

    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(),
            'solicitor_id'       => $user->solicitor_id,
            'wip_grade'          => $user->wip_grade,
        ]);
    }

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

        $this->validate([
            'solicitor_id' => 'nullable|exists:solicitors,id',
            'wip_grade' => 'nullable|in:C,D',
        ]);

        $previousRoles = $this->user->roles->pluck('name')->toArray();
        $targetLabel   = "{$this->user->name_first} {$this->user->name_last}";

        $this->user->update([
            'name_first'         => $this->name_first,
            'name_last'          => $this->name_last,
            'email_address'      => $this->email,
            'username'           => $this->username,
            'solicitor_id'       => $this->solicitor_id,
            'wip_grade'          => $this->wip_grade,
        ]);

        $changedFields = array_keys($this->user->getChanges());

        if ($changedFields) {
            $historyService->add(
                auth()->user(),
                "Updated user '{$targetLabel}' (" . implode(', ', $changedFields) . ")",
                [
                    'target_user_id' => $this->user->id,
                    'fields'         => $changedFields,
                ]
            );
        }

        if ($this->password) {
            $this->user->update([
                'password' => bcrypt($this->password),
            ]);
            $historyService->add(
                auth()->user(),
                "Reset password for user '{$targetLabel}'",
                ['target_user_id' => $this->user->id]
            );
        }

        $this->user->syncRoles($this->roles);

        $added   = array_values(array_diff($this->roles, $previousRoles));
        $removed = array_values(array_diff($previousRoles, $this->roles));

        if ($added || $removed) {
            $parts = [];
            if ($added)   $parts[] = "added: " . implode(', ', $added);
            if ($removed) $parts[] = "removed: " . implode(', ', $removed);

            $historyService->add(
                auth()->user(),
                "Updated roles for user '{$targetLabel}' — " . implode('; ', $parts),
                [
                    'target_user_id' => $this->user->id,
                    'added'          => $added,
                    'removed'        => $removed,
                ]
            );
        }

        $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(),
            'solicitors' => Solicitor::orderBy('name')->get(),
        ]);
    }
}
