<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Validator;
use App\Responses;
use App\Helper;
use App\Models\Devices;
use App\Models\Vehicles;
use App\Models\UserLogs;
use Auth;

class DevicesController extends Controller
{
	public function view_devices(Request $req)
	{
		$vhcs = Vehicles::listVehicles($req->auth);
		$data = [
			"vhcs" => $vhcs,
		];

		$log = [
			"module" => "Device",
			"action" => "View",
			"desc" => "Open Device menu",
		];
		UserLogs::insert(Auth::user()->id, $log);
		return view("menu_v1.configs.devices", $data);
	}

	/**
	 * API
	 */

	public function api_list_devices(Request $req)
	{
		try {
			$now = time();
			$input = [];
			$rulesInput = [];

			// validasi input
			// $isValidInput = Validator::make($input, $rulesInput);
			// if (!$isValidInput->passes()) {
			// 	$apiResp = Responses::bad_input($isValidInput->messages()->first());
			// 	return new Response($apiResp, $apiResp['meta']['code']);
			// }

			$list = Devices::listDevices();
			foreach ($list as $key => $row) {
				$list[$key]->DT_RowIndex = $key + 1;
				$list[$key]->action = "-";
				if ($row->vhc_id == null) {
					$list[$key]->is_idle = "yes";
				} else {
					$list[$key]->is_idle = "no";
				}
			}

			$apiResp = Responses::success("success list devices");
			$apiResp["count"] = count($list);
			$apiResp["data"] = $list;
			return new Response($apiResp, $apiResp["meta"]["code"]);
		} catch (\Exception $e) {
			$apiResp = Responses::error($e->getMessage());
			return new Response($apiResp, $apiResp["meta"]["code"]);
		}
	}

	public function api_show_device(Request $req, $id)
	{
		try {
			$now = time();

			$input = [
				"id" => $id,
			];
			$rulesInput = [
				"id" => "required|integer|not_in:0",
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp["meta"]["code"]);
			}

			$device = Devices::showDeviceById($id);
			if (count($device) < 1) {
				$apiResp = Responses::not_found("device not found");
				return new Response($apiResp, $apiResp["meta"]["code"]);
			}

			$apiResp = Responses::success("success get detail device");
			$apiResp["data"] = $device[0];
			return new Response($apiResp, $apiResp["meta"]["code"]);
		} catch (\Exception $e) {
			$apiResp = Responses::error($e->getMessage());
			return new Response($apiResp, $apiResp["meta"]["code"]);
		}
	}

	public function api_add_device(Request $req)
	{
		try {
			$now = time();

			$input = [
				"device_id" => $req->device_id,
				"name" => $req->name,
				"simcard" => $req->simcard,
				"type" => $req->type,
				"status" => $req->status,
				"assigned" => $req->assigned,
				"vid" => $req->vid,
				"available" => $req->available,
				"protocol" => $req->protocol,
			];
			$rulesInput = [
				"device_id" => "required|numeric",
				"name" => "required|string",
				"simcard" => "required|numeric",
				"type" => "required|integer|not_in:0",
				"status" => "required|numeric|min:0",
				"assigned" => "required|numeric",
				"vid" => "nullable|numeric",
				"available" => "required|numeric",
				"protocol" => "string",
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp["meta"]["code"]);
			}

			$device_id = str_pad($req->device_id, Devices::MAX_DEVICE_ID, "0", STR_PAD_LEFT);
			if (strlen($device_id) > 16) {
				$apiResp = Responses::bad_request("Device ID must be a maximum of 16 digits");
				return new Response($apiResp, $apiResp["meta"]["code"]);
			}
			if (strlen($req->simcard) > 14) {
				$apiResp = Responses::bad_request("SIM card number must be a maximum of 14 digits");
				return new Response($apiResp, $apiResp["meta"]["code"]);
			}

			$uniqDeviceId = Devices::getDeviceByDeviceId($device_id);
			if (count($uniqDeviceId) > 0) {
				$apiResp = Responses::bad_request("device id has been used");
				return new Response($apiResp, $apiResp["meta"]["code"]);
			}
			$uniqSimcard = Devices::getDeviceBySimcard($req->simcard);
			if (count($uniqSimcard) > 0) {
				$apiResp = Responses::bad_request("simcard has been used");
				return new Response($apiResp, $apiResp["meta"]["code"]);
			}

			DB::beginTransaction();

			$insDevice = [
				"device_id" => $device_id,
				"name" => $req->name,
				"simcard" => (int) $req->simcard,
				"type" => $req->type,
				"is_active" => $req->status,
				"is_assigned" => $req->assigned,
				"is_available" => $req->available,
				"crt" => $now,
				"crt_by" => $req->auth->uid,
				"updt" => $now,
				"updt_by" => $req->auth->uid,
				"protocol" => $req->protocol,
			];
			$id = Devices::addDevice($insDevice);

			if ($req->assigned == Devices::IS_ASSIGNED) {
				if ($req->vid == null || $req->vid == "") {
					DB::rollBack();
					$apiResp = Responses::bad_request("Vehicle has not been selected");
					return new Response($apiResp, $apiResp["meta"]["code"]);
				}
				$vhc = Vehicles::getVehicleByDeviceId($device_id);
				if (count($vhc) > 0) {
					DB::rollBack();
					$apiResp = Responses::bad_request(
						"The vehicle is already assigned to device ID " . $vhc[0]->device_id
					);
					return new Response($apiResp, $apiResp["meta"]["code"]);
				}
				$vhc = Vehicles::getVehicleById($req->vid);
				if (count($vhc) > 0 && $vhc[0]->dvc_id !== 0 && $vhc[0]->device_id !== $device_id) {
					DB::rollBack();
					$apiResp = Responses::bad_request(
						"The vehicle is already assigned to device ID " . $vhc[0]->device_id
					);
					return new Response($apiResp, $apiResp["meta"]["code"]);
				}
				$vid = $req->vid;
				Vehicles::updateVehicle($vid, [
					"dvc_id" => $id,
					"device_id" => $device_id,
					"simcard" => (int) $req->simcard,
				]);
			} else {
				$vid = 0;
			}

			$apiResp = Responses::created("success add new device");

			DB::commit();

			$log = [
				"module" => "Device",
				"action" => "Create",
				"desc" => "Add new device: " . $device_id,
			];
			UserLogs::insert(Auth::user()->id, $log);
			return new Response($apiResp, $apiResp["meta"]["code"]);
		} catch (\Exception $e) {
			DB::rollBack();
			$apiResp = Responses::error($e->getMessage());
			return new Response($apiResp, $apiResp["meta"]["code"]);
		}
	}

	public function api_updt_device(Request $req, $id)
	{
		try {
			$now = time();

			$input = [
				"id" => $id,
				"device_id" => $req->device_id,
				"name" => $req->name,
				"simcard" => $req->simcard,
				"type" => $req->type,
				"status" => $req->status,
				"assigned" => $req->assigned,
				"vid" => $req->vid,
				"available" => $req->available,
				"protocol" => $req->protocol,
			];
			$rulesInput = [
				"id" => "required|integer|not_in:0",
				"device_id" => "required|numeric",
				"name" => "required|string",
				"simcard" => "required|numeric",
				"type" => "required|integer|not_in:0",
				"status" => "required|numeric",
				"assigned" => "required|numeric",
				"vid" => "nullable|numeric",
				"available" => "required|numeric",
				"protocol" => "string",
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp["meta"]["code"]);
			}

			$device = Devices::showDeviceById($id);
			if (count($device) < 1) {
				$apiResp = Responses::not_found("device not found");
				return new Response($apiResp, $apiResp["meta"]["code"]);
			}

			$device_id = str_pad($req->device_id, Devices::MAX_DEVICE_ID, "0", STR_PAD_LEFT);
			if (strlen($device_id) > 16) {
				$apiResp = Responses::bad_request("Device ID must be a maximum of 16 digits");
				return new Response($apiResp, $apiResp["meta"]["code"]);
			}
			if (strlen($req->simcard) > 14) {
				$apiResp = Responses::bad_request("SIM card number must be a maximum of 14 digits");
				return new Response($apiResp, $apiResp["meta"]["code"]);
			}

			$uniqDeviceId = Devices::getDeviceByDeviceId($device_id);
			if (count($uniqDeviceId) > 0) {
				$notSameUser = 1;
				foreach ($uniqDeviceId as $key => $row) {
					if ($row->id == $id) {
						$notSameUser = 0;
					}
				}
				if ($notSameUser) {
					$apiResp = Responses::bad_request("device id has been used");
					return new Response($apiResp, $apiResp["meta"]["code"]);
				}
			}
			$uniqSimcard = Devices::getDeviceBySimcard($req->simcard);
			if (count($uniqSimcard) > 0) {
				$notSameUser = 1;
				foreach ($uniqSimcard as $key => $row) {
					if ($row->id == $id) {
						$notSameUser = 0;
					}
				}
				if ($notSameUser) {
					$apiResp = Responses::bad_request("simcard has been used");
					return new Response($apiResp, $apiResp["meta"]["code"]);
				}
			}

			if ($req->status == Devices::IS_INACTIVE) {
				$isUsed = Vehicles::getVehicleByDeviceId($device_id);
				if (count($isUsed) > 0) {
					$apiResp = Responses::bad_request("Cannot deactivate, the device is currently in use.");
					return new Response($apiResp, $apiResp["meta"]["code"]);
				}
			}

			DB::beginTransaction();

			if ($device[0]->vhc_id) {
				Vehicles::updateVehicle($device[0]->vhc_id, [
					"dvc_id" => 0,
					"device_id" => str_pad(0, Devices::MAX_DEVICE_ID, "0", STR_PAD_LEFT),
					"simcard" => 0,
				]);
			}

			if ($req->assigned == Devices::IS_ASSIGNED) {
				if ($req->vid == null || $req->vid == "") {
					DB::rollBack();
					$apiResp = Responses::bad_request("Vehicle has not been selected");
					return new Response($apiResp, $apiResp["meta"]["code"]);
				}
				$vhc = Vehicles::getVehicleById($req->vid);
				if (count($vhc) > 0 && $vhc[0]->dvc_id !== 0 && $vhc[0]->device_id !== $device_id) {
					DB::rollBack();
					$apiResp = Responses::bad_request(
						"This vehicle is already linked to a device  " . $vhc[0]->device_id
					);
					return new Response($apiResp, $apiResp["meta"]["code"]);
				}
				$vid = $req->vid;
				Vehicles::updateVehicle($vid, [
					"dvc_id" => $id,
					"device_id" => $device_id,
					"simcard" => (int) $req->simcard,
				]);
			} else {
				$vhc = Vehicles::getVehicleByDeviceId($device_id);
				if (count($vhc) > 0) {
					$vid = $vhc[0]->id;
					Vehicles::updateVehicle($vid, [
						"dvc_id" => 0,
						"device_id" => str_pad(0, Devices::MAX_DEVICE_ID, "0", STR_PAD_LEFT),
						"simcard" => 0,
					]);
				}
			}

			$updtDevice = [
				"device_id" => $req->device_id,
				"name" => $req->name,
				"simcard" => (int) $req->simcard,
				"type" => $req->type,
				"is_active" => $req->status,
				"is_assigned" => $req->assigned,
				"is_available" => $req->available,
				"updt" => $now,
				"updt_by" => $req->auth->uid,
				"protocol" => $req->protocol,
			];
			Devices::updateDevice($id, $updtDevice);

			$apiResp = Responses::created("success update device");

			DB::commit();

			$log = [
				"module" => "Device",
				"action" => "Update",
				"desc" => "Edit device: " . $device_id,
			];
			UserLogs::insert(Auth::user()->id, $log);
			return new Response($apiResp, $apiResp["meta"]["code"]);
		} catch (\Exception $e) {
			DB::rollBack();
			$apiResp = Responses::error($e->getMessage());
			return new Response($apiResp, $apiResp["meta"]["code"]);
		}
	}

	public function api_del_device(Request $req, $id)
	{
		try {
			$now = time();

			$input = [
				"id" => $id,
			];
			$rulesInput = [
				"id" => "required|integer|not_in:0",
			];

			// validasi input
			$isValidInput = Validator::make($input, $rulesInput);
			if (!$isValidInput->passes()) {
				$apiResp = Responses::bad_input($isValidInput->messages()->first());
				return new Response($apiResp, $apiResp["meta"]["code"]);
			}

			$device = Devices::showDeviceById($id);
			if (count($device) < 1) {
				$apiResp = Responses::not_found("Device not found");
				return new Response($apiResp, $apiResp["meta"]["code"]);
			}

			$isUsed = Vehicles::getVehicleByDeviceId($device[0]->device_id);
			if (count($isUsed) > 0) {
				$apiResp = Responses::bad_request("Cannot delete, the device is currently in use");
				return new Response($apiResp, $apiResp["meta"]["code"]);
			}

			DB::beginTransaction();

			Devices::updateDevice($id, [
				"dlt" => $now,
				"dlt_by" => $req->auth->uid,
			]);

			DB::commit();

			$apiResp = Responses::success("success delete device");

			$log = [
				"module" => "Device",
				"action" => "Delete",
				"desc" => "Delete device : " . $device[0]->device_id,
			];
			UserLogs::insert(Auth::user()->id, $log);
			return new Response($apiResp, $apiResp["meta"]["code"]);
		} catch (\Exception $e) {
			DB::rollBack();
			$apiResp = Responses::error($e->getMessage());
			return new Response($apiResp, $apiResp["meta"]["code"]);
		}
	}
}
