<?php

namespace App\Services\Asset;

use App\Events\BulkUpdates;
use App\Http\Traits\CountryBasedFilterTrait;
use App\Models\Asset;
use App\Models\AssetStatus;
use App\Models\Location;
use App\Services\Integrations\Tickets\TicketManagementService;
use App\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

class ReturnAssetService
{
    /**
     * Initializes the class with a TicketManagementService instance.
     *
     * @param TicketManagementService $ticketManagementService The service for managing tickets.
     */
    public function __construct(protected TicketManagementService $ticketManagementService) {}

    /**
     * Processes the return of an asset by validating input data,
     * updating ticket and asset history, and handling child assets.
     *
     * @param array $inputData The input data containing asset details and return information.
     * @param User $user The user initiating the return process.
     * @param string $i Optional index for handling multiple assets in bulk operations.
     * 
     * @return bool Returns false if validation fails, true if the return process is successful.
     */
    public function returnAsset($inputData, $user, $i = '')
    {
        if ($this->validateReturn($inputData, $i) === true) {
            return false;
        }

        $asset = Asset::find($inputData['asset_id' . $i]);

        $oldroomname = $this->getOldRoomName($asset);

        $this->createTicketHistory($asset, $user, $oldroomname, $inputData, $i);

        $this->createAssetHistory($asset, $oldroomname, $inputData, $i);

        $this->updateReturn($asset, $inputData, $i);

        //Updating the history for each child asset
        if ($asset->has('childrenAsset')) {
            foreach ($asset->childrenAsset as $assetChild) {
                $this->getOldRoomName($assetChild);
                $this->createTicketHistory($assetChild, $user, $oldroomname, $inputData, $i);
                $this->createAssetHistory($assetChild, $oldroomname, $inputData, $i);
                $this->updateReturn($assetChild, $inputData, $i);
            }
        }

        return true;
    }

    /**
     * Validates the return data for an asset.
     *
     * @param array $inputData The input data to be validated.
     * @param string $i The index of the asset (optional).
     * @return bool True if the validation fails, false otherwise.
     */
    public function validateReturn($inputData, $i = '')
    {
        $assetIdKey = 'asset_id' . $i;
        $toLocationIdKey = 'to_location_id' . $i;
        $assetStatusIdKey = 'asset_status_id' . $i;
        $ticketNoKey = 'ticket_no' . $i;

        $validator = Validator::make($inputData, [
            $toLocationIdKey => ['required', 'integer'],
            // $ticketNoKey => ['required', 'string'],
            $assetIdKey => ['required', 'integer'],
            $assetStatusIdKey => ['required', 'integer'],
        ]);

        return $validator->fails();
    }

    /**Get old Room name
     * @param mixed $asset
     * 
     * @return [type]
     */
    public function getOldRoomName($asset)
    {
        $oldroomname = '';
        if ($asset->location != null) {
            $oldroomname = optional($asset->location)->room_name;
        } else {
            if ($asset->user_id) {
                $roomname =  User::select('id', 'first_name', 'last_name')->where('id', $asset->user_id)->first();
                $oldroomname = $roomname?->first_name . ' ' . $roomname?->last_name;
            }
        }
        return $oldroomname;
    }


    /**
     * Creates a ticket history entry for the given asset.
     *
     * @param mixed $asset The asset to create the ticket history for.
     * @param mixed $user The user associated with the asset.
     * @param string $oldroomname The old room name of the asset.
     * @param mixed $inputData Additional input data for the ticket history.
     * @param int|null $i Optional index for the ticket history.
     *
     * @return bool True if the ticket history was created successfully.
     */
    public function createTicketHistory($asset, $user, $oldroomname, $inputData, $i = null)
    {
        $ticketCommentstext = formatTicketComment($inputData['comments' . $i] ?? '');
        $ticketDescription = __('jira.Returned', [
            'assetid' => $asset->id,
            'assetname' => $asset->serial_no,
            'oldroomname' => $oldroomname,
            'newroomname' => optional(Location::findOrFail($inputData['to_location_id' . $i]))->room_name,
            'commenttext' => $ticketCommentstext,
            'username' => $user->first_name . ' ' . $user->last_name,
            'useremail' => $user->email,
        ]);
        $this->ticketManagementService->addComment(Auth::id(), ($inputData['ticket_no' . $i] ?? null), $ticketDescription, "Asset Returned");

        return true;
    }


    /**
     * Creates an asset history entry for the given asset.
     *
     * @param mixed $asset The asset to create the asset history for.
     * @param string $oldroomname The old room name of the asset.
     * @param mixed $inputData Additional input data for the asset history.
     * @param int|null $i Optional index for the asset history.
     *
     * @return bool True if the asset history was created successfully.
     */
    public function createAssetHistory($asset, $oldroomname, $inputData, $i = null)
    {
        $commentstext = ($inputData['comments' . $i] != NULL ?  " with comments \"" . $inputData['comments' . $i] . "\"" : "");

        $oldStatusName = AssetStatus::find($asset->asset_status_id)?->name;
        $newStatusName = AssetStatus::find($inputData['asset_status_id' . $i])?->name;

        $description = __('history.Returned', [
            'assetid' => $asset->id,
            'assetname' => $asset->serial_no,
            'oldroomname' => $oldroomname,
            'newroomname' => optional(Location::findOrFail($inputData['to_location_id' . $i]))->room_name,
            'commenttext' => $commentstext,
            'oldassetstatus' => $oldStatusName,
            'newassetstatus' => $newStatusName,
        ]);

        $userId = NULL;
        if ($asset->user_id) {
            $userId = $asset->user_id;
        }

        $locationId = NULL;
        if ($asset->location_id) {
            $locationId = $asset->location_id;
        }

        $assetHistory = [
            'user_id' => Auth::id(),
            'asset_id' => $asset->id,
            'ticket_no' => $inputData['ticket_no' . $i] ?? null,
            'action' => 'returned',
            'comments' => $inputData['comments' . $i],
            'old_location_id' => $locationId,
            'new_location_id' => $inputData['to_location_id' . $i],
            'old_user_id' => $userId,
            'new_user_id' => NULL,
            'old_asset_status_id' => $asset->asset_status_id,
            'new_asset_status_id' => $inputData['asset_status_id' . $i],
            'old_value' => $oldStatusName,
            'new_value' => $newStatusName,
            '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;
    }

    /**
     * Updates an asset's return information.
     *
     * @param mixed $asset The asset to be updated.
     * @param mixed $inputData The input data for the update.
     * @param int|null $i The index of the asset (optional).
     *
     * @return bool Whether the update was successful.
     */
    public function updateReturn($asset, $inputData, $i = null)
    {
        return $asset->update([
            'location_id' => $inputData['to_location_id' . $i],
            'user_id' => NULL,
            'asset_status_id' => $inputData['asset_status_id' . $i],
        ]);
    }
}
