<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Validator;
use Hidehalo\Nanoid\Client as Nanoid;
use App\Responses;
use App\Helper;
use App\Models\Tracks;
use App\Models\Zone;
use App\Models\Users;
use App\Models\Clients;
use App\Models\ClientsDivs;
use App\Models\ClientsDivGroups;
use App\Models\ConfRates;
use App\Models\Region;

class InjectController extends Controller
{
	/**
	 * API
	 */

	//  GPS Zones.xlsx
	public function add_gps_zones_v1(Request $req)
	{
		try {

			$apiResp = Responses::bad_request('service unavailable');
			return (new Response($apiResp, $apiResp['meta']['code']));

			$now = time();

			$input = [
				'Sheet1' => $req->Sheet1,
			];
			$rulesInput = [
				'Sheet1' => 'required|array',
				'Sheet1.*.NAME' => 'required|string|max:255',
				'Sheet1.*.COMPANY' => 'required|string|max:255',
				'Sheet1.*.DIVISION' => 'required|string|max:255',
				'Sheet1.*.GROUP' => 'required|string|max:255',
				'Sheet1.*.TYPE' => 'required|string|max:255',
				'Sheet1.*.TYPE ID' => 'required|numeric',
				'Sheet1.*.COLOR' => 'required|string|min:7|max:7',
				'Sheet1.*.ADDRESS' => 'required|string',
				'Sheet1.*.SHIP-TO CODE' => 'nullable|string',
				'Sheet1.*.SHAPE' => 'required|numeric',
				'Sheet1.*.BOUNDARY' => 'required|string',
				'Sheet1.*.GEONAMES' => 'nullable|string',
				'Sheet1.*.COMPANIES' => 'nullable|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']);
			}

			DB::beginTransaction();

			foreach ($req->Sheet1 as $keyTop => $row) {
				$now = time();
				$zid = null;
				$cid = Clients::DEFAULT_CID;
				$c_div_id = ClientsDivs::DEFAULT_CID;
				$c_div_group_id = ClientsDivGroups::DEFAULT_CID;
				$uniqClient = Clients::getClientByName($row['COMPANY']);
				if (count($uniqClient) > 0) {
					$cid = $uniqClient[0]->id;
				} else {
					$insClient = [
						'c_name' => $row['COMPANY'],
						'c_addr_office' => $row['ADDRESS'],
						'c_phone' => 81288789878,
						'c_phone_code' => Clients::DEFAULT_PHONE_CODE,
						'c_mail' => 'inject@gmail.com',
						'pic_name' => $row['COMPANY'],
						'pic_phone' => 81288789878,
						'pic_phone_code' => Clients::DEFAULT_PHONE_CODE,
						'pic_mail' => 'inject@gmail.com',
						'c_status' => Clients::CSTTS_ACTIVE,
						'crt' => $now,
						'crt_by' => Users::DEFAULT_UID,
						'updt' => $now,
						'updt_by' => Users::DEFAULT_UID,
					];
					$cid = Clients::addClient($insClient);
				}
				$uniqCDiv = ClientsDivs::getCDivByName($row['DIVISION']);
				if (count($uniqCDiv) > 0) {
					$c_div_id = $uniqCDiv[0]->id;
				} else {
					$insCDiv = [
						'client_id' => $cid,
						'name' => $row['DIVISION'],
						'crt' => $now,
						'crt_by' => Users::DEFAULT_UID,
						'updt' => $now,
						'updt_by' => Users::DEFAULT_UID,
					];
					$c_div_id = ClientsDivs::addCDiv($insCDiv);
				}
				$uniqCDivGroup = ClientsDivGroups::getCDivGroupByName($row['GROUP']);
				if (count($uniqCDivGroup) > 0) {
					$c_div_group_id = $uniqCDivGroup[0]->id;
				}

				$uniqZone = Zone::getZoneByName($row['NAME']);
				if (count($uniqZone) > 0) {
					$zid = $uniqZone[0]->id;
				} else {
					$boundary_latlngs = [];
					$radius = 0;
					$boundary_type = Zone::ZONE_BOUNDARY_POLYGON;
					$workflow_type = Zone::ZONE_WORKFLOW_DEST;

					if (strpos(strtolower($row['TYPE']), 'bongkar') !== false) {
						$workflow_type = Zone::ZONE_WORKFLOW_DEST;
					} else if (strpos(strtolower($row['TYPE']), 'muat') !== false) {
						$workflow_type = Zone::ZONE_WORKFLOW_PICKUP;
					} else if (strpos(strtolower($row['TYPE']), 'park') !== false) {
						$workflow_type = Zone::ZONE_WORKFLOW_PARKING;
					} else if (strpos(strtolower($row['TYPE']), 'bengkel') !== false) {
						$workflow_type = Zone::ZONE_WORKFLOW_SERVICE;
					}

					$boundarys = explode('|', $row['BOUNDARY']);
					foreach ($boundarys as $k => $v) {
						$latLng = explode(',', $v);
						$boundary_latlngs[] = [
							'lat' => $latLng[0],
							'lng' => $latLng[1],
						];
					}

					$row['SHAPE']; // 1=>circle,0=>polygon
					if ($row['SHAPE'] == 1) {
						$boundary_type = Zone::ZONE_BOUNDARY_CIRCLE;
						$radius = Helper::haversineGreatCircleDistance($boundary_latlngs[0]['lat'], $boundary_latlngs[0]['lng'], $boundary_latlngs[1]['lat'], $boundary_latlngs[1]['lng']);
					}

					$insZone = [
						'name' => $row['NAME'],
						'type' => Zone::ZONE_TYPE_WAREHOUSE,
						'workflow_type' => $workflow_type,
						'shiptocode' => 0,
						'fulladdress' => $row['ADDRESS'],
						'boundary_type' => $boundary_type,
						'boundary_hex_color' => strtoupper($row['COLOR']),
						'boundary_latlngs' => json_encode($boundary_latlngs),
						'boundary_bounds' => null,
						'boundary_radius' => $radius,
						'status' => Zone::STATUS_ACTIVE,
						'client_group_id' => $cid,
						'crt' => $now,
						'crt_by' => Users::DEFAULT_UID,
						'updt' => $now,
						'updt_by' => Users::DEFAULT_UID,
					];
					$insZone['boundary_points'] = "ST_GeomFromText('MULTIPOINT(";
					foreach ($boundary_latlngs as $key => $val) {
						$insZone['boundary_points'] .= $val['lng'] . " " . $val['lat'] . ", ";
					}
					$insZone['boundary_points'] = substr($insZone['boundary_points'], 0, -2); // remove 2 last character
					$insZone['boundary_points'] .= ")')";
					$insZone['boundary_points'] = DB::raw($insZone['boundary_points']);

					// dump($insZone);
					// if ($keyTop == 5) {
					// 	dd('stop');
					// }
					$zoneId = Zone::addZone($insZone);
				}
			}

			$apiResp = Responses::created('success inject add new zone');

			DB::commit();
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			DB::rollBack();
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	//  B_8074_AS_Positions_01-Feb-2022_06-Feb-2022.xlsx
	/**
	 * 00000000AB8021AS == 0000000128021119
	 * 000000000B8026AS == 0000000028026119
	 * 000000000B8038AS == 0000000028038119
	 * 000000000B8074AS == 0000000028074119
	 * 000000000B8129AS == 0000000028129119
	 * 000000000B8224AS == 0000000028223119
	 */
	public function add_vhc_tracks_v1(Request $req)
	{
		try {
			$now = time();

			$apiResp = Responses::bad_request('service unavailable');
			return (new Response($apiResp, $apiResp['meta']['code']));

			$input = [
				'Sheet1' => $req->Sheet1,
			];
			$rulesInput = [
				'Sheet1' => 'required|array',
				'Sheet1.*.DIVISION' => 'required|string|max:255',
				'Sheet1.*.GROUP' => 'required|string|max:255',
				'Sheet1.*.TIMESTAMP' => 'required|string|max:255',
				'Sheet1.*.VEHICLE' => 'required|string|max:12',
				'Sheet1.*.DRIVER' => 'nullable|string',
				'Sheet1.*.ZONE' => 'nullable|string',
				'Sheet1.*.LOCATION' => 'required|string',
				'Sheet1.*.LATITUDE' => 'required|string|max:25',
				'Sheet1.*.LONGITUDE' => 'required|string|max:25',
				'Sheet1.*.SPEED (kph)' => 'required|numeric',
				'Sheet1.*.COURSE (°)' => 'required|numeric',
				'Sheet1.*.IGINITION' => 'nullable|string|max:2',
				'Sheet1.*.ENGINE STATUS' => 'required|string|max:25',
				'Sheet1.*.VEHICLE MILEAGE (km)' => 'required|string',
				'Sheet1.*.FUEL LEVEL (%)' => 'nullable|numeric',
				'Sheet1.*.POWER TAKEOFF' => 'nullable|numeric',
			];
			// pre_milleage, sum_milleage

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

			DB::beginTransaction();

			foreach ($req->Sheet1 as $key => $row) {
				$now = time();
				$track_id = null;

				$crt = strtotime($row['TIMESTAMP']);
				$crt_format = date('Y-m-d h:i:s', $crt);

				// $nopol = explode(' ', $row['VEHICLE']);
				$device_id = '0000000028223119'; // 16 digits

				$ignition = null;
				if ($row['IGNITION'] == 'ON') {
					$ignition = 1;
				} else {
					$ignition = 2;
				}

				$en_status = null;
				if ($row['ENGINE STATUS'] == 'Moving') {
					$en_status = 2; // moving
				} else {
					$en_status = 1; // idling
				}

				$insTracks = [
					'original_hex' => '78781f12',
					'protocol' => 'gt06',
					'action' => 'location',
					'device_id' => $device_id,
					'latitude' => $row['LATITUDE'],
					'longitude' => $row['LONGITUDE'],
					'speed' => $row['SPEED (kph)'] ?? null,
					'orientation' => $row['COURSE (°)'] ?? null,
					'ignition' => $ignition, // 1 on, 2 off.
					'stts_engine' => $en_status, // 1 idling, 2 moving
					'stts_reverse_geo' => 1, // 1 sudah reverse
					'pre_milleage' => null,
					'sum_milleage' => $row['VEHICLE MILEAGE (km)'],
					'crt' => $crt,
					'crt_format' => $crt_format,
				];
				$track_id = Tracks::addTracks($insTracks);

				$insTracksAddr = [
					'master_id' => $track_id,
					'device_id' => $device_id,
					'type' => 2, // inject
					'lat' => $row['LATITUDE'],
					'lng' => $row['LONGITUDE'],
					'zone_name' => $row['ZONE'] ?? null,
					'country_id' => 1,
					'country_code' => 'id',
					'country_text' => 'INDONESIA',
					'fulladdress' => $row['LOCATION'] ?? null,
					'stts_reverse_geo' => 1, // 1 sudah reverse
					'crt' => $crt,
					'crt_format' => $crt_format,
				];
				Tracks::addTracksAddr($insTracksAddr);
			}

			$apiResp = Responses::created('success inject add new tracks');

			DB::commit();
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			DB::rollBack();
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}

	//  Publish Rate Bingkis.xlsx
	public function add_conf_rate_v1(Request $req)
	{
		try {
			$apiResp = Responses::bad_request('service unavailable');
			return (new Response($apiResp, $apiResp['meta']['code']));

			$now = time();

			// $exists = Storage::disk('local')->get('PublishRateBingkis.xlsx');
			// dd($exists);

			// $file = fopen(__DIR__.'/../../../storage/app/PublishRateBingkis.xlsx', 'r');
			// //Output lines until EOF is reached
			// while(! feof($file)) {
			// 	$line = fgets($file);
			// 	echo $line. "<br>";
			// }
			// fclose($file);
			// return false;

			// dd($req->input());

			// DB::beginTransaction();

			$lanes = ConfRates::getLanesActive();

			foreach ($req['Publish Rate'] as $keyTop => $row) {
				$nanoid = new Nanoid();
				$code = $nanoid->formattedId('123456789', 6);

				$uniqCode = ConfRates::getRateByCode($code);
				if (count($uniqCode) > 0) {
					$code = $nanoid->formattedId('123456789', 6);
					$uniqCode = ConfRates::getRateByCode($code);
					if (count($uniqCode) > 0) {
						$code = $nanoid->formattedId('123456789', 6);
						$uniqCode = ConfRates::getRateByCode($code);
						if (count($uniqCode) > 0) {
							$code = $nanoid->formattedId('123456789', 6);
						}
					}
				}

				$lead_time = explode('-', $row['Lead Time']);
				$fast_time = trim($lead_time[0]);
				if (count($lead_time) == 1) {
					$long_time = trim($lead_time[0]);
				} else {
					$long_time = trim(explode('hari', $lead_time[1])[0]);
				}

				$lane_id = 0;
				foreach ($lanes as $k => $v) {
					if ($lane_id === 0) {
						if (strpos($v->name, $row['Via']) !== false) {
							$lane_id = $v->id;
						}
					}
				}

				$prid = Region::getLikeProv($row['Dest Province']);
				if ($prid) {
					$prid = $prid[0]->kodeProv;
				} else {
					$prid = 0;
				}

				$city_name = $row['Dest City'];
				$district_name = $row['Dest City'];
				if (strpos($row['Dest City'], '(') !== false) {
					$part = explode('(', $row['Dest City']);
					$pos = strpos($part[1], ')');
					$part[1] = substr($part[1], 0, $pos);

					$district_name = trim($part[0]);
					$city_name = trim($part[1]);
				}

				$ktid = Region::getLikeCity($city_name);
				if ($ktid) {
					$kodeKab = 0;
					foreach ($ktid as $city) {
						if ($city->kodeProv == $prid) {
							$kodeKab = $city->kodeKab;
						}
					}
					$ktid = $kodeKab;
				} else {
					$ktid = 0;
				}
				$kcid = Region::getLikeDistrict($district_name);
				if ($kcid) {
					$kodeKab = $ktid;
					$kodeKec = 0;
					foreach ($kcid as $district) {
						if ($district->kodeProv == $prid) {
							if ($kodeKab === 0) {
								$kodeKab = $district->kodeKab;
								$kodeKec = $district->kodeKec;
							} else {
								if ($kodeKab === $district->kodeKab) {
									$kodeKec = $district->kodeKec;
								}
							}
							$kodeKec = $district->kodeKec;
						}
					}
					$ktid = $kodeKab;
					$kcid = $kodeKec;
				} else {
					$kcid = 0;
				}

				if ($ktid === 0) {
					$city_name = trim($part[0]);
					$district_name = trim($part[1]);

					$ktid = Region::getLikeCity($city_name);
					if ($ktid) {
						$kodeKab = 0;
						foreach ($ktid as $city) {
							if ($city->kodeProv == $prid) {
								$kodeKab = $city->kodeKab;
							}
						}
						$ktid = $kodeKab;
					} else {
						$ktid = 0;
					}
					$kcid = Region::getLikeDistrict($district_name);
					if ($kcid) {
						$kodeKab = $ktid;
						$kodeKec = 0;
						foreach ($kcid as $district) {
							if ($district->kodeProv == $prid) {
								if ($kodeKab === 0) {
									$kodeKab = $district->kodeKab;
									$kodeKec = $district->kodeKec;
								} else {
									if ($kodeKab === $district->kodeKab) {
										$kodeKec = $district->kodeKec;
									}
								}
								$kodeKec = $district->kodeKec;
							}
						}
						$ktid = $kodeKab;
						$kcid = $kodeKec;
					} else {
						$kcid = 0;
					}
				}

				$insRate = [
					'code' => $code,
					'origin_prov' => 31,
					// 'origin_city' => $row->origin_city,
					'lane' => $lane_id,
					'dest_prov' => $prid,
					'dest_city' => $ktid,
					'dest_district' => $kcid,
					'fast_time' => $fast_time,
					'long_time' => $long_time,
					'unit_time' => ConfRates::UNIT_DAY,
					'sell_kg' => (int)str_replace(',', '', str_replace('Rp', '', $row['Sell KG'])),
					'buy_kg' => (int)str_replace(',', '', str_replace('Rp', '', $row['Buy KG'])),
					'margin_kg' => (int)str_replace(',', '', str_replace('Rp', '', $row['Margin'])),
					'percent_kg' => number_format(str_replace('%', '', $row['Persentase']), 2, '.', ','),
					'sell_cbm' => (int)str_replace(',', '', str_replace('Rp', '', $row[' Sell CBM '])),
					'buy_cbm' => (int)str_replace(',', '', str_replace('Rp', '', $row[' Buy CBM '])),
					'margin_cbm' => (int)str_replace(',', '', str_replace('Rp', '', $row['Margin_1'])),
					'percent_cbm' => number_format(str_replace('%', '', $row['Persentase_1']), 2, '.', ','),
					'is_active' => ConfRates::IS_ACTIVE,
					'crt' => $now,
					'crt_by' => 1,
					'updt' => $now,
					'updt_by' => 1,
				];

				// dump($insRate);
				// if ($keyTop > 5) {
				// 	dd('stop');
				// }
				$rid = ConfRates::addRate($insRate);
			}

			$apiResp = Responses::created('success inject add new conf rate');

			// DB::commit();
			return (new Response($apiResp, $apiResp['meta']['code']));
		} catch (\Exception $e) {
			DB::rollBack();
			$apiResp = Responses::error($e->getMessage());
			return (new Response($apiResp, $apiResp['meta']['code']));
		}
	}
}
