<?php

namespace App\Http\Controllers\Assets;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Requests\ValidationsRequest;
use App\Models\Asset;
use App\Models\AssetStatus;
use App\Services\Integrations\Tickets\TicketManagementService;
use Facades\App\Services\JiraService;
use App\User;

class ValidationsController extends Controller
{


	public function __construct(protected TicketManagementService $ticketManagementService) {}

	/**
	 * Validates if an asset can be moved or not.
	 *
	 * @param ValidationsRequest $request
	 * @return \Illuminate\Http\JsonResponse
	 */
	public function canBeMoved(ValidationsRequest $request)
	{
		$asset = Asset::select('id', 'location_id', 'asset_tag', 'serial_no', 'asset_type_id', 'asset_status_id')->getByTagAndSerial(request('asset_tag'))->first();

		if ($asset === null) {
			return response()->json(['status' => false, 'message' => 'Asset not found.']);
		}

		if ($this->checkAssetType(request('type')) === false) {
			return response()->json(['status' => false, 'message' => 'Not a valid asset.']);
		}

		if (optional($asset->location)->is_freeze === 1) {
			return response()->json(['status' => false, 'message' => 'Asset from freezed location cannot be moved.']);
		}

		return response()->json(['status' => $asset->canBeMoved(), 'message' => 'Sorry, the asset can not be moved.']);
	}

	/**
	 * Checks if an asset can be linked to another asset.
	 *
	 * @param  \App\Http\Requests\ValidationsRequest  $request
	 * @return \Illuminate\Http\JsonResponse
	 */
	public function canBeLinked(ValidationsRequest $request)
	{
		$asset = Asset::select('id', 'location_id', 'asset_tag', 'serial_no', 'asset_type_id', 'asset_status_id')->getByTagAndSerial(request('asset_tag'))->first();

		if ($asset === null) {
			return response()->json(['status' => false, 'message' => 'Asset not found.']);
		}

		if ($this->checkAssetType(request('type')) === false) {
			return response()->json(['status' => false, 'message' => 'Not a valid asset.']);
		}

		return response()->json(['status' => $asset->canBeLinked(), 'message' => 'Sorry, the asset can not be linked.']);
	}

	/**
	 * Validates if an asset can be returned or not.
	 *
	 * @param  \App\Http\Requests\ValidationsRequest  $request
	 * @return \Illuminate\Http\JsonResponse
	 */
	public function canBeReturned(ValidationsRequest $request)
	{
		$asset = Asset::select('id', 'location_id', 'asset_tag', 'serial_no', 'asset_type_id', 'asset_status_id')->getByTagAndSerial(request('asset_tag'))->first();

		if ($asset === null) {
			return response()->json(['status' => false, 'message' => 'Asset not found.']);
		}

		if ($this->checkAssetType(request('type')) === false) {
			return response()->json(['status' => false, 'message' => 'Not a valid asset.']);
		}

		return response()->json(['status' => $asset->canBeReturned(), 'message' => 'Sorry, the asset can not be returned.']);
	}

	/**
	 * Validates if an asset can be updated to a given status or not.
	 *
	 * @param  \App\Http\Requests\ValidationsRequest  $request
	 * @return \Illuminate\Http\JsonResponse
	 */
	public function canBeUpdated(ValidationsRequest $request)
	{
		$statusSlug = AssetStatus::getName($request->asset_status_id)->first()->slug;
		$asset      = Asset::select('id', 'location_id', 'asset_tag', 'serial_no', 'asset_type_id', 'asset_status_id')->getByTagAndSerial($request->asset_tag);

		if (optional($asset->first())->asset_status_id) {
			$currentStatusSlug = AssetStatus::find($asset->first()->asset_status_id)->slug;

			if (!in_array($statusSlug, config('asset-status.' . $currentStatusSlug))) {
				$data['status'] = false;
				$data['currentStatus'] = AssetStatus::find($asset->first()->asset_status_id)->name;
				$data['newStatus'] = AssetStatus::getName(request('asset_status_id'))->first()->name;

				return response()->json($data);
			}
		}

		$data['status'] = true;
		$data['currentStatus'] = '';
		$data['newStatus'] = '';

		return response()->json($data);
	}

	public function typeChecked()
	{
		if (request('type') == 'avassets') {
			return Asset::assetypeValidateAvasset(request('asset_tag'));
		} else if (request('type') == 'mobile') {
			return Asset::assetypeValidateMobile(request('asset_tag'));
		} else if (request('type') == 'network') {
			return Asset::assetypeValidateNetwork(request('asset_tag'));
		} else if (request('type') == 'research') {
			return Asset::assetypeValidateResearch(request('asset_tag'));
		} else {
			return Asset::assetypeValidateIt(request('asset_tag'));
		}
	}

	public function checkUnique()
	{
		if ($this->getName() == 'serial_no') {
			$serialNo = stripS(request('value'));

			if (Asset::where('serial_no', $serialNo)->exists()) {
				return response()->json(false);
			} else {
				return response()->json(true);
			}
		}

		if ($this->getName() == 'asset_tag') {
			$assetTag = request('value');
			$assetTagLength = strlen($assetTag);

			while ($assetTagLength < 6) {
				$assetTag = '0' . $assetTag;
				$assetTagLength++;
			}

			$assetTag = $assetTag;

			if (Asset::where('asset_tag', $assetTag)->exists()) {
				return response()->json(false);
			} else {
				return response()->json(true);
			}
		}

		if (Asset::where($this->getName(), request('value'))->exists()) {
			return response()->json(false);
		} else {
			return response()->json(true);
		}
	}

	public function checkExists()
	{
		if (Asset::where('serial_no', request('value'))->orWhere('asset_tag', request('value'))->exists()) {
			return response()->json(true);
		} else {
			return response()->json(false);
		}
	}

	public function checkParent()
	{
		if (request('type') == "it") {
			if (Asset::where($this->getName(), request('value'))->parent()->count() > 0) {
				return response()->json(true);
			} else {
				return response()->json(false);
			}
		} else if (request('type') == "server") {
			if (Asset::where($this->getName(), request('value'))->parentServer()->count() > 0) {
				return response()->json(true);
			} else {
				return response()->json(false);
			}
		} else if (request('type') == "mobile") {
			if (Asset::where($this->getName(), request('value'))->parentMobile()->count() > 0) {
				return response()->json(true);
			} else {
				return response()->json(false);
			}
		}
	}

	public function checkChild()
	{
		if (request('type') == "it") {
			if (Asset::where($this->getName(), request('value'))->child()->count() > 0) {
				return response()->json(true);
			} else {
				return response()->json(false);
			}
		} else if (request('type') == "server") {
			if (Asset::with('assetType')->where('asset_tag', request('value'))->get()->first()->assettype->slug != "servers") {
				if (Asset::where($this->getName(), request('value'))->childServer()->count() > 0) {
					return response()->json(true);
				} else {
					return response()->json(false);
				}
			} else {
				return response()->json(true);
			}
		} else if (request('type') == "mobile") {
			if (Asset::where($this->getName(), request('value'))->childMobile()->count() > 0) {
				return response()->json(true);
			} else {
				return response()->json(false);
			}
		}
	}

	public function getName()
	{
		$name = request('name');

		if ($name == 'parent_serial_no' || $name == 'child_serial_no') {
			$name = 'serial_no';
		}

		if ($name == 'parent_asset_tag' || $name == 'child_asset_tag') {
			$name = 'asset_tag';
		}

		return $name;
	}

	/**
	 * Check the requested ticket exists or not
	 * @return [type]
	 */
	public function ticketExist()
	{
		if (request('ticket_no')) {
			return response()->json($this->ticketManagementService->checkTicketExists(request('ticket_no')));
		}

		return false;
	}

	/**
	 * The function checks if a given asset tag or serial # exists and if its location is not
	 * frozen.
	 *
	 * @return a JSON response. If the asset is found and has a location, it will return true if the
	 * location is not frozen (is_freeze == 0), and false otherwise. If the asset is not found or does
	 * not have a location, it will return false.
	 */
	function checkFreezeLocation()
	{
		if ($asset = Asset::select('id', 'location_id')->with('location:id,is_freeze')->where('asset_tag', request('value'))->orWhere('serial_no', request('value'))->first()) {
			return optional($asset->location)->is_freeze == 1 ? response()->json(false) : response()->json(true);
		}

		return response()->json(false);
	}

	/**
	 * Checks the asset type based on the provided type and asset tag.
	 *
	 * @param string $type The type of asset to check.
	 * @return bool True if the asset type is valid, false otherwise.
	 */
	private function checkAssetType($type)
	{
		if ($type == 'avassets') {
			return Asset::assetypeValidateAvasset(request('asset_tag'));
		} else if (request('type') == 'mobile') {
			return Asset::assetypeValidateMobile(request('asset_tag'));
		} else if (request('type') == 'network') {
			return Asset::assetypeValidateNetwork(request('asset_tag'));
		} else if (request('type') == 'research') {
			return Asset::assetypeValidateResearch(request('asset_tag'));
		} else {
			return Asset::assetypeValidateIt(request('asset_tag'));
		}
	}
}
