<?php

namespace App\Services\Asset;

use App\Events\BulkUpdates;
use App\Models\Asset;
use App\Models\Location;
use App\Services\Integrations\Tickets\TicketManagementService;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

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

    /**
     * Move an asset to a new location and update the ticket and asset history.
     *
     * @param array $inputData The input data containing the asset ID, location ID, ticket number, and comments.
     * @param User $user The user performing the move operation.
     * @param string $i The optional index for the asset in case of bulk moves.
     *
     * @return bool Returns true if the move operation was successful.
     */
    public function moveAsset($inputData, $user, $i = '')
    {
        if ($this->validateMove($inputData, $i) === true) {
            return false;
        }

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

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

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

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

        //While moving the parent asset then move child assets also
        if ($asset->has('childrenAsset')) {

            foreach ($asset->childrenAsset as $assetChild) {

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

                $this->createAssetHistory($assetChild, $inputData, $i);

                $this->updateMove($assetChild, $inputData, $i);
            }
        }

        return true;
    }

    /**
     * Validates the move operation by checking if the input data contains the required fields.
     *
     * @param array $inputData The input data to be validated.
     * @param int $i The index of the asset being moved.
     *
     * @return bool True if the validation fails, false otherwise.
     */
    public function validateMove($inputData, $i = '')
    {
        $assetIdKey = 'asset_id' . $i;
        $toLocationIdKey = 'to_location_id' . $i;
        $ticketNoKey = 'ticket_no' . $i;

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

        return $validator->fails();
    }

    /**
     * Creates a ticket history for the given asset and user.
     *
     * @param mixed $asset The asset to create the ticket history for.
     * @param mixed $user The user associated with the ticket history.
     * @param array $inputData The input data containing the comments and location IDs.
     * @param int|null $i The optional index for the asset history.
     * @return bool Returns true if the ticket history was created successfully.
     */
    public function createTicketHistory($asset, $user, $inputData, $i = null)
    {
        $ticketCommentstext = formatTicketComment($inputData['comments' . $i]);
        $ticketDescription = __('jira.Moved', [
            'assetname' => $asset->serial_no,
            'assetid' => $asset->id,
            'oldroomname' => optional($asset->location)->room_name,
            '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 Moved");

        return true;
    }

    /**
     * Creates a new asset history entry for the given asset.
     *
     * @param mixed $asset The asset to create the history entry for.
     * @param array $inputData The input data containing the comments, ticket number, and location IDs.
     * @param int|null $i The optional index for the asset history.
     * @return bool Returns true if the asset history entry was created successfully.
     */
    public function createAssetHistory($asset, $inputData, $i = null)
    {
        $commentstext = ($inputData['comments' . $i] != NULL ?  " with comments \"" . $inputData['comments' . $i] . "\"" : "");
        $description = __('history.Moved', [
            'assetname' => $asset->serial_no,
            'assetid' => $asset->id,
            'oldroomname' => optional($asset->location)->room_name,
            'newroomname' => optional(Location::findOrFail($inputData['to_location_id' . $i]))->room_name,
            'commenttext' => $commentstext,
        ]);

        $assetHistory = [
            'user_id' => Auth::id(),
            'asset_id' => $asset->id,
            'ticket_no' => $inputData['ticket_no' . $i] ?? null,
            'action' => 'moved',
            'comments' => $inputData['comments' . $i],
            'old_location_id' => optional($asset->location)->id,
            'new_location_id' => $inputData['to_location_id' . $i],
            'old_value' => optional($asset->location)->room_name,
            'new_value' => optional(Location::findOrFail($inputData['to_location_id' . $i]))->room_name,
            '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 the location ID of an asset.
     *
     * @param mixed $asset The asset to update.
     * @param array $inputData The input data containing the location ID.
     * @param int|null $i The optional index for the input data.
     * @return bool Returns true if the asset was updated successfully, false otherwise.
     */
    public function updateMove($asset, $inputData, $i = null)
    {
        return $asset->update([
            'location_id' => $inputData['to_location_id' . $i]
        ]);
    }
}
