<?php

namespace App\Observers;

use App\User;
use App\Models\UserType;
use App\Services\Asset\UpdateStatusService;
use App\Services\Settings\History\UserRoleChangeHistoryService;

class UserObserver
{
    /**
     * Constructor for the class.
     *
     * @param UserRoleChangeHistoryService $roleChangeHistoryService The data service for role change history.
     */
    public function __construct(protected UserRoleChangeHistoryService $roleChangeHistoryService, protected UpdateStatusService $updateStatusService) {}

    /**
     * Handle the User "updating" event.
     */
    public function updating(User $user): void
    {
        // if user is terminated updates the user to employee role.
        $this->updateTermUsersToEmployee($user);

        // Add a history for a user's role change
        $this->createRoleChangeHistory($user);
    }

    /**
     * Handle the User "updated" event.
     *
     * @param User $user The user whose assets need to be updated.
     * @return void
     */
    public function updated(User $user)
    {
        $this->updateTerminatedUserAssetsToPendingReturn($user);
    }

    /**
     * Updates the Terminated user to an employee.
     *
     * @param object $user The user object.
     * @throws ModelNotFoundException If the user is not found.
     * @return bool Returns false if the update fails, otherwise void.
     */
    public function updateTermUsersToEmployee($user)
    {
        if (!$user->isDirty('status') || $user->status !== 0) {
            return false;
        }

        $oldUser = User::select('id', 'user_type_id', 'status')->with('userType:id,name')->findOrFail($user->id);

        if (in_array($oldUser?->userType?->name, ['Super Admin'])) {
            return false;
        }
        $userTypeId = UserType::select('id')->where('name', 'Employee')->value('id');

        if (!$userTypeId || $oldUser->user_type_id === $userTypeId) {
            return false;
        }

        $user->user_type_id = $userTypeId;
        $user->syncRoles(['Employee']);

        return true;
    }

    /**
     * Create a role change history if the user's user_type_id has been modified.
     *
     * @param User $user The user object.
     * @return void
     */
    public function createRoleChangeHistory($user)
    {
        if ($user->isDirty('user_type_id') === TRUE) {
            $this->roleChangeHistoryService->addRoleChangeHistory($user);
        }
    }

    /**
     * Updates the status of assets belonging to a terminated user to pending return.
     *
     * @param User $user The user whose assets need to be updated.
     * @return void
     */
    private function updateTerminatedUserAssetsToPendingReturn($user)
    {
        // Check if the user status has changed to 0 (terminated)
        if (!$user->isDirty('status') || $user->status !== 0) {
            return;
        }

        $this->updateStatusService->updateTerminatedUserAssetsToPendingReturn($user);
    }
}
