<?php

namespace App\Services\Api\Slackbot;

use Illuminate\Http\Request;
use App\Events\BulkUpdates;
use App\Models\Asset;
use App\Models\AssetStatus;
use Carbon\Carbon;

/**
 * Service class for the Loaner return date update
 */
class LoanerReturnDateService extends SlackbotApiService
{

    /**
     * Get the asset to update based on the user's email and asset serial number.
     *
     * @param Request $request The incoming request instance.
     *
     * @return array The response containing the asset data or an error message.
     */
    public function getAssetToUpdate(Request $request)
    {
        $validAssetStatus = AssetStatus::where('slug', config('slackbot.asset_status.loaned'))->first();

        $user = $this->getUserByEmail($request->user_email);

        if (isset($user['error']) && $user['error'] == true) {
            return $user;
        }

        // Check permission.
        if (!$user->can('Slackbot Admin Tools')) {
            return $this->getErrorResponse('You do not have permission to update this asset');
        }

        $asset = Asset::with('assetStatus')
            ->where(function ($query) use ($request) {
                $query->where('asset_tag', $request->serial_no)
                    ->orWhere('serial_no', $request->serial_no);
            })
            ->first();

        if (!$asset) {
            return $this->getErrorResponse('Asset not found in Teqtivity');
        }

        // Checking the asset status.
        if (optional($validAssetStatus)->id != $asset->asset_status_id) {
            return $this->getErrorResponse('Asset status should be ' . $validAssetStatus->name);
        }

        return $this->getSuccessReponse($asset, 'Asset');
    }

    /**
     * Update the return date of an asset.
     *
     * @param Request $request The incoming request instance.
     *
     * @return array The response indicating success or containing an error message.
     */
    public function updateReturnDate(Request $request)
    {
        // Valdiate fields.
        $validation = $this->validateFields($request);

        if (isset($validation['error']) && $validation['error'] == true) {
            return $validation;
        }

        $asset = $this->getAssetToUpdate($request);

        if (isset($validation['error']) && $validation['error'] == true) {
            return $asset;
        }

        $this->updateAssetAndCreateHistory($asset['data'], $request);

        return $this->getSuccessReponse($asset, 'Expected Return Date Updated');
    }

    /**
     * Validate the required fields in the request.
     *
     * @param \Illuminate\Http\Request $request The incoming request object containing user input.
     *
     * @return mixed Returns true if all required fields are present, otherwise returns an error response.
     */
    public function validateFields($request)
    {
        if (empty($request->user_email) || empty($request->serial_no) || empty($request->loaner_date)) {
            return $this->getErrorResponse('Something went wrong. Try again later');
        }

        return true;
    }

    /**
     * Update the loaner return date of an asset and create a history entry.
     *
     * @param Asset   $asset   The asset object to be updated.
     * @param Request $request The incoming request object containing user input.
     *
     * @return bool Returns true if the asset was updated and the history entry was created successfully.
     */
    public function updateAssetAndCreateHistory($asset, $request)
    {
        // Update the Expected Return Date.
        $user = $this->getUserByEmail($request->user_email);
        $assetOldValue = $asset->loaner_return_date;

        $asset->loaner_return_date = parse_date_from_db_date(request('loaner_date'));
        $asset->save();

        $description = __('history.LoanerReturnDateUpdated', [
            'assetid' => $asset->id,
            'assetName' => $asset->serial_no,
            'oldReturnDate' => $assetOldValue,
            'newReturnDate' => $asset->loaner_return_date,
        ]);

        $assetHistory = [
            'user_id' => $user->id,
            'asset_id' => $asset->id,
            'action' => 'loanerReturnDate_updated',
            'old_value' => $assetOldValue,
            'new_value' => $asset->loaner_return_date,
            'description' => $description,
            'created_at'  => Carbon::now()->format('Y-m-d H:i:s'),
            'updated_at'  => Carbon::now()->format('Y-m-d H:i:s'),
        ];

        event(new BulkUpdates($assetHistory));

        return true;
    }
}
