<?php

namespace App\Http\Controllers;

use App\Models\Activity;
use App\Models\AssignMaterial;
use App\Models\AssignTools;
use App\Models\CommentActivity;
use App\Models\Holiday;
use App\Models\Link;
use App\Models\Project;
use App\Models\ReportActivity;
use App\Models\ReportActivityMaterial;
use App\Models\TemplateGantt;
use App\Models\UserToActivity;
use App\Models\VersionGantt;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;

class ActivityController extends Controller
{
	public function getByGanttId($id, $proyek_id)
	{
		if(Activity::where("version_gantt_id", $id)->count() == 0)
			$dataGantt = $this->getDataActivity($id);

		$this->templateToActivity($id, $proyek_id);
		$dataGantt = $this->getDataActivity($id);

		return response()->json(['status'=>'success','data'=> $dataGantt,'code'=>200], 200);
	}

	private function getDataActivity($id)
	{

		$dataHeader = Activity::where('version_gantt_id', $id)->where('type_activity', 'header')->first();
		$startDate = date_create($dataHeader->start_date);
		$endDate = date_create($dataHeader->end_date);
		$dataHeader->start_date = date_format($startDate,"Y-m-d H:i:s");
		$dataHeader->end_date = date_format($endDate,"Y-m-d H:i:s");
		$dataHeader->type = "project";
		$dataHeader->text = $dataHeader->name;
		$finalData[] = $dataHeader;
		$data = Activity::where('version_gantt_id', $id)->where('parent_id', $dataHeader->id)->orderBy('id', 'asc')->get();

		if(Activity::where('version_gantt_id', $id)->where('type_activity', 'header')->count() == 0)
			$data = Activity::where('version_gantt_id', $id)->whereNull('parent_id')->orderBy('id', 'asc')->get();

		foreach($data as $objRow){
			$type = "project";
			if($objRow->type_activity=="milestone")
				$type = $objRow->type_activity;
			if(empty($dataChildren))
				$type = "task";

			$objRow->text = $objRow->name;
			$objRow->parent = $objRow->parent_id ? $objRow->parent_id : null;
			$startDate = date_create($objRow->start_date);
			$endDate = date_create($objRow->end_date);
			$objRow->jobs_done = $this->sumVolumeActualMaterial($objRow->id);
			$objRow->assign_hr = $this->getUserActivity($objRow->id);
			$objRow->assign_tools = $this->getToolsActivity($objRow->id);
			$objRow->assign_material = $this->getMaterialActivity($objRow->id);
			$objRow->start_date = date_format($startDate,"Y-m-d H:i:s");
			$objRow->end_date = date_format($endDate,"Y-m-d H:i:s");
			$objRow->planned_start = isset($objRow->planned_start) ? date_format(date_create($objRow->planned_start),"Y-m-d H:i:s") : NULL;
			$objRow->planned_end = isset($objRow->planned_end) ? date_format(date_create($objRow->planned_end),"Y-m-d H:i:s") : NULL;
			$objRow->progress = (int)$objRow->persentase_progress/100;
			$dataChildren = $this->getChildren($id, $objRow->id);
			$objRow->type = $type;
			$finalData[] = $objRow;
			$finalData = array_merge($finalData, $dataChildren);
		}

		$dataLink = Link::where('version_gantt_id', $id)->get();
		$finalLink = [];
		foreach($dataLink as  $objRow)
		{
			$dataRow = array(
				'id'=>$objRow->id,
				'source'=>$objRow->s_activity_id,
				'target'=>$objRow->t_activity_id,
				'type'=>$objRow->type_link,
				'code'=>$objRow->code_link
			);
			if($objRow->lag)
				$dataRow['lag'] = $objRow->lag;
			$finalLink[] = $dataRow;
		}

		$resultData = array(
			"data"=>$finalData,
			"links"=>$finalLink
		);

		return $resultData;
	}

	private function getChildren($gantt_id, $parent_id)
	{
		$finalData = [];
		$data = Activity::where('version_gantt_id', $gantt_id)->where('parent_id', $parent_id)->orderBy('id', 'asc')->get();
		foreach($data as $objRow){
			$objRow->parent = $parent_id;
			$objRow->text = $objRow->name;
			$objRow->jobs_done = $this->sumVolumeActualMaterial($objRow->id);
			$objRow->assign_hr = $this->getUserActivity($objRow->id);
			$objRow->assign_tools = $this->getToolsActivity($objRow->id);
			$objRow->assign_material = $this->getMaterialActivity($objRow->id);
			$objRow->progress = (int)$objRow->persentase_progress/100;
			$startDate = date_create($objRow->start_date);
			$endDate = date_create($objRow->end_date);
			$objRow->start_date = date_format($startDate,"Y-m-d H:i:s");
			$objRow->end_date = date_format($endDate,"Y-m-d H:i:s");
			$objRow->planned_start = isset($objRow->planned_start) ? date_format(date_create($objRow->planned_start),"Y-m-d H:i:s") : NULL;
			$objRow->planned_end = isset($objRow->planned_end) ? date_format(date_create($objRow->planned_end),"Y-m-d H:i:s") : NULL;
			$dataChildren = $this->getChildren($gantt_id, $objRow->id);
			if($objRow->type_activity=="milestone"){
				$objRow->type = $objRow->type_activity;
			}elseif(empty($dataChildren)){
				$objRow->type = "task";
			}else{
				$objRow->type = "project";
			}
			$finalData[] = $objRow;
			$finalData = array_merge($finalData, $dataChildren);
		}
		return $finalData;
	}

	private function sumVolumeActualMaterial($id)
	{
		$tmpPercentage = [];

		$dataPlan = AssignMaterial::where('activity_id', $id)->get();
		if($dataPlan->isEmpty())
			return 0;

		foreach ($dataPlan as $value) {
			$tmpPercentage[] = 100;
			$getDataVolActual = ReportActivityMaterial::where('assign_material_id', '=', $value->id)->sum("qty");
			$percentage = ($getDataVolActual * 100) / $value->qty_planning;
			if($value->status_activity != 'done'){
				$tmpPercentage[] = $percentage >= 100 ? 90 : $percentage;
			}
		}

		return array_sum($tmpPercentage) > 0 ? array_sum($tmpPercentage) / count($tmpPercentage) : 0;
	}

	private function getUserActivity($id)
	{
		return Arr::flatten(UserToActivity::select("u.name as name")
			->join("m_users as u", "u.id", "=", "assign_hr_to_activity.user_id")
			->where('assign_hr_to_activity.activity_id', $id)
			->get()
			->toArray());
	}

	private function getMaterialActivity($id)
	{
		return Arr::flatten(AssignMaterial::select("m.description as name")
			->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
			->where('assign_material_to_activity.activity_id', $id)
			->get()
			->toArray());
	}

	private function getToolsActivity($id)
	{
		return Arr::flatten(AssignTools::select("m.name as name")
			->join("m_tools_resource as m", "m.id", "=", "assign_tools_to_activity.tools_id")
			->where('assign_tools_to_activity.activity_id', $id)
			->get()
			->toArray());
	}

	private function templateToActivity($id, $proyek_id)
	{
		$project = Project::findOrFail($proyek_id);

		$rootActivity = Activity::create([
			'version_gantt_id'=>$id,
			'proyek_id'=>$proyek_id,
			'name'=> $project->nama,
			'kode_sortname'=>$project->kode_sortname,
			'start_date'=> $project->mulai_proyek,
			'end_date'=> $project->akhir_proyek,
			'rencana_biaya'=> str_replace(".","", $project->rencana_biaya),
			'type_activity'=> 'header',
			'created_by'=>$this->currentName,
		]);

		$resultTypeProject = TemplateGantt::where('proyek_type_id',$project
			->type_proyek_id)
			->whereNull('parent_id')
			->orderByRaw('id ASC')
			->get();

		foreach($resultTypeProject as $objRow){
			$childActivities = TemplateGantt::where("parent_id", $objRow->id)->count();
			$resultNew = Activity::create([
				'type_activity'=> $childActivities > 0 ? "project" : "task",
				'version_gantt_id'=>$id,
				'parent_id'=>$rootActivity->id,
				'proyek_id'=>$proyek_id,
				'name'=> $objRow->name_activity,
				'start_date'=>date("Y-m-d H:i:s"),
				'end_date'=>date("Y-m-d H:i:s"),
				'created_by'=>$this->currentName
			]);
			$this->getChildrenTemplate($id, $objRow->id, $project->type_project_id ,$proyek_id, $resultNew->id, $project->mulai_proyek);
		}
	}

	private function getChildrenTemplate($id, $parent_id, $type_proyek_id, $proyek_id, $parent_new, $firstDay)
	{
		$data = TemplateGantt::where('proyek_type_id', $type_proyek_id)->where('parent_id', $parent_id)->orderByRaw('id ASC')->get();
		foreach($data as $objRow){
			$childActivities = TemplateGantt::where("parent_id", $objRow->id)->count();
			$resultNew = Activity::create([
				'type_activity'=> $childActivities > 0 ? "project" : "task",
				'version_gantt_id'=>$id,
				'parent_id'=>$parent_new,
				'proyek_id'=>$proyek_id,
				'name'=> $objRow->name_activity,
				'start_date'=>$firstDay,
				'end_date'=>$firstDay,
				'created_by'=>$this->currentName
			]);
			$this->getChildrenTemplate($id, $objRow->id, $type_proyek_id, $proyek_id, $resultNew->id, $firstDay);
		}
	}

	public function add(Request $request)
	{
		$this->validate($request, [
			'version_gantt_id'=>'required'
		]);

		$data = $request->all();
		$data['name'] = $request->text;
		$data['persentase_progress'] = $request->progress;
		$data['created_by'] = $this->currentName;
		$data['type_activity'] = "task";

		$parent = $data['parent_id'] ?? null;
		if($parent){
			$this->updateTypeProject($parent);
			CommentActivity::where('activity_id', $parent)->delete();
			UserToActivity::where('activity_id', $parent)->delete();
		}

		if(!$result = Activity::create($data))
			return response()->json(['status'=>'failed','action'=>'error','code'=> 500], 500);

		return response()->json(['status'=>'success','action'=>'inserted', 'tid'=>$result->id,'code'=>200], 200);
	}

	private function updateTypeProject($id)
	{
		Activity::find($id)->update(["type_activity"=>"project"]);
	}

	public function edit($id){
		if(empty($id) || !is_int((int)$id))
			return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);

		if(!$result = Activity::find($id))
			return response()->json(['status'=>'failed','message'=>'Data not found!','code'=> 404], 404);

		return response()->json(['status'=>'success','code'=>200,'data'=> $result], 200);
	}

	public function update(Request $request, $id)
	{
		if(empty($id) || !is_int((int)$id))
			return response()->json(['status'=>'failed', 'action'=>'error','message'=>'id is required!','code'=>400], 400);

		$updateBobot = false;
		$data = Activity::findOrFail($id);
		if(!$data = Activity::find($id))
			return response()->json(['status'=>'failed', 'action'=>'error','message'=>'Data not found!','code'=> 404], 404);
		$parent = $data->parent_id;
		$dataUpdate = $request->all();

		$oldRencanaBiaya = $data->rencana_biaya;
		$newRencanaBiaya = str_replace(",",".",$request->rencana_biaya);
		if($oldRencanaBiaya != $newRencanaBiaya)
			$updateBobot = true;

		$dataUpdate['name'] = $request->text;
		$dataUpdate['persentase_progress'] = $request->progress*100;
		$dataUpdate['updated_by'] = $this->currentName;
		if($data->type_activity!='header')
			$dataUpdate['type_activity'] = $request->type;

		if(!$data->update($dataUpdate))
			return response()->json(['status'=>'failed', 'action'=>'error','message'=>'data activity failed updated!','code'=>400], 400);

		if($parent){
			$this->updateCostPlanning($parent);
			$this->updatePersentaseProgress($parent);
			$this->updateCostActual($parent);
		}

		$this->calculateAllBobot($data->proyek_id, $data->version_gantt_id);

		return response()->json(['status'=>'success','update_bobot'=> $updateBobot, 'data'=>$dataUpdate, 'action'=>'updated','message'=>'Activity updated!','code'=>200], 200);
	}

	public function updateRegular(Request $request, $id){
		if(empty($id) || !is_int((int)$id))
			return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);

		$data = Activity::find($id);

		if(!$data = Activity::find($id))
			return response()->json(['status'=>'failed','message'=>'Data not found!','code'=> 404], 404);

		if(!$data->update($request->all()))
			return response()->json(['status'=>'failed','message'=>'Failed to update!','code'=> 500], 500);

		return response()->json(['status'=>'success','message'=>'Activity Updated!','code'=> 200], 200);
	}

	private function calculateAllBobot($proyek, $gantt)
	{
		if(Activity::where('version_gantt_id', $gantt)->where("proyek_id", $proyek)->where('type_activity', 'header')->count() == 0)
			$totalCost = Activity::select(
					DB::raw('sum(cast(rencana_biaya as double precision))')
				)
				->where("proyek_id", $proyek)
				->where("version_gantt_id", $gantt)
				->whereNull("parent_id")
				->first();

		$rootActivity = Activity::where('version_gantt_id', $gantt)
			->where("proyek_id", $proyek)
			->where('type_activity', 'header')
			->first();

		$totalCost = Activity::select(DB::raw('sum(cast(rencana_biaya as double precision))'))
			->where("proyek_id", $proyek)
			->where("version_gantt_id", $gantt)
			->where("parent_id", $rootActivity->id)
			->first();

		if($totalCost->sum > 0){
			$activities = Activity::where("proyek_id", $proyek)->where("version_gantt_id", $gantt)->get();
			foreach ($activities as $activity) {
				$activity->update([
					"bobot_planning" => ( (int)$activity->rencana_biaya / $totalCost->sum ) * 100,
					"updated_by" => $this->currentName
				]);
			}
		}
		return true;
	}

	public function delete($id)
	{
		$data = Activity::findOrFail($id);

		if(!$data = Activity::find($id))
			return response()->json(['status'=>'failed', 'action'=>'error','message'=> 'Data not found!','code'=> 404], 404);

		if($data->parent_id){
			$this->checkForUpdateParent($data->parent_id);
			$this->updateCostPlanning($data->parent_id);
			$this->updatePersentaseProgress($data->parent_id);
			$this->updateCostActual($data->parent_id);
		}

		if(!$data->delete())
			return response()->json(['status'=>'failed', 'action'=>'error','message'=>'data activity failed deleted!','code'=> 500], 500);

		return response()->json(['status'=>'success', "action"=>"deleted",'message'=>'data activity successfully deleted!','code'=>200], 200);
	}

	private function checkForUpdateParent($id)
	{
		if(Activity::where("parent_id", $id)->count() == 0)
			Activity::find($id)->update(["type_activity"=>"task"]);
	}

	public function getUpdate($id)
	{
		if(!$data = Activity::find($id))
			return response()->json(['status'=>'failed', 'action'=>'error','message'=> 'Data not found!','code'=>400], 400);

		$data->progress = (int) $data->persentase_progress / 100;
		$data->rencana_biaya = str_replace(".", ",", $data->rencana_biaya);
		$data->jobs_done = $this->sumVolumeActualMaterial($data->id);
		$data->assign_hr = $this->getUserActivity($data->id);
		$data->assign_tools = $this->getToolsActivity($data->id);
		$data->assign_material = $this->getMaterialActivity($data->id);
		return response()->json(['status'=>'success', "data"=> $data,'code'=>200], 200);
	}

	private function updateCostPlanning($id)
	{
		$sumBiaya = Activity::select(DB::raw('sum(cast(rencana_biaya as double precision))'))
			->where("parent_id", $id)
			->first();

		$activity = Activity::find($id);
		$data= array(
			"rencana_biaya" => $sumBiaya->sum,
			"updated_by" => $this->currentName
		);

		if($activity->update($data) && $activity->parent_id)
			$this->updateCostPlanning($activity->parent_id);
	}

	private function updatePersentaseProgress($id)
	{
		$siblings = Activity::where("parent_id", $id);
		$sumProgress = $siblings->sum("persentase_progress");
		$totalChild = $siblings->count();
		$activity = Activity::find($id);

		$activity->update([
			"persentase_progress" => $sumProgress / $totalChild,
			"updated_by" => $this->currentName
		]);
		if($activity->parent_id)
			$this->updatePersentaseProgress($activity->parent_id);
	}

	private function updateCostActual($id)
	{
		$activity = Activity::find($id);

		$activity->update([
			"biaya_actual" => Activity::where("parent_id", $id)->sum("biaya_actual"),
			"updated_by" => $this->currentName
		]);
		if($activity->parent_id)
			$this->updateCostActual($activity->parent_id);
	}

	public function search(Request $request)
	{
		$dataBuilder = $this->setUpPayload($request->all(), 'm_activity');
		$builder = $dataBuilder['builder'];
		$countBuilder = $dataBuilder['count'];
		$dataGet = $builder->get();
		$totalRecord = $countBuilder->count();
		return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
	}

	public function getPercentagePerDay(Request $request)
	{
		$dataPayload = $request->all();
		$allGantt  = [];
		foreach ($dataPayload['project_id'] as $val) {
			$allGantt[] = $this->getLatestGantt($val);
		}

		$dataFinal=[];
		foreach ($allGantt as $val) {
			$dataProject = Project::find($val['proyek_id']);
			$holidays = Holiday::where("version_gantt_id", $val['last_gantt_id'])->where("proyek_id", $val['proyek_id'])->get();
			$dateHoliday = []; //$holiday->all();
			foreach ($holidays as $holiday) {
				$startH = new \DateTime($holiday->date);
				$endH = clone $startH;
				$endH->modify('+'.$holiday->duration.' day');
				$intervalH = \DateInterval::createFromDateString('1 day');
				$periodH = new \DatePeriod($startH, $intervalH, $endH);
				foreach ($periodH as $dt) {
					$dateHoliday[] = $dt->format("Y-m-d");
				}
			}
			$verGantt = VersionGantt::find($val['last_gantt_id']);
			$configOff = $verGantt->config_dayoff;
			if($configOff && $configOff!= ""){
				$dayOff = explode(",", $verGantt->config_dayoff);
				$dayOff = array_map(
					function($value) { return (int)$value; },
						$dayOff
				);
			}else{
				$dayOff = [];
			}
			$checkHeader = Activity::where('type_activity', 'header')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->count();
			if($checkHeader > 0){
				$dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->first();
				$minDate = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->min("start_date");
				$maxDate = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->max("end_date");
			}else{
				$minDate = Activity::whereNull('parent_id')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->min("start_date");
				$maxDate = Activity::whereNull('parent_id')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->max("end_date");
			}

			$begin = new \DateTime($minDate);
			$end = new \DateTime($maxDate);
			$end = $end->modify( '+1 day' );
			$interval = \DateInterval::createFromDateString('1 day');
			$period = new \DatePeriod($begin, $interval, $end);
			$checkHeader = Activity::where('type_activity', 'header')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->count();
			if($checkHeader > 0){
				$dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->first();
				$totalRencanaBudget = Activity::select(DB::raw('sum(cast(rencana_biaya as integer))'))->where('parent_id', $dataHeader->id)->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->first();
			}else{
				$totalRencanaBudget = Activity::select(DB::raw('sum(cast(rencana_biaya as integer))'))->whereNull('parent_id')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->first();
			}

			$totalRencanaBudget = $totalRencanaBudget->sum;
			$currentPercentage = 0;
			$dataDate = [];
			$dataPercen = [];
			foreach ($period as $dt) {
				$weekDay = $dt->format("w");
				$currentDate = $dt->format("Y-m-d");
				if(!in_array($weekDay, $dayOff) && !in_array($currentDate, $dateHoliday))
				{
					$totalPercentage = 0;
					$checkHeader = Activity::where('type_activity', 'header')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->count();
					if($checkHeader > 0){
						$dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->first();
						$dataActivity = Activity::whereRaw("'".$currentDate."' BETWEEN DATE(m_activity.start_date) AND DATE(m_activity.end_date)")->where('parent_id', $dataHeader->id)->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->get();
					}else{
						$dataActivity = Activity::whereRaw("'".$currentDate."' BETWEEN DATE(m_activity.start_date) AND DATE(m_activity.end_date)")->whereNull('parent_id')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->get();
					}

					foreach ($dataActivity as $activity) {
						$duration = $activity->duration;
						if($totalRencanaBudget > 0 && $duration > 0){
							$totalPercentage = $totalPercentage + ((($activity->rencana_biaya/$totalRencanaBudget)*100)/$duration);
						}
					}
					$currentPercentage = $currentPercentage + $totalPercentage;
					$dataDate[] = $currentDate;
					$dataPercen[] = $currentPercentage;
				}else{
					$dataDate[] = $currentDate;
					$dataPercen[] = "dateOff";
				}
			}
			$dataPercentage = array(
				"date"=>$dataDate,
				"percentage"=>$dataPercen
			);
			$dataFinal[] = array(
				"proyek_name"=> $dataProject->nama,
				"data"=>$dataPercentage
			);
		}

		if($dataFinal){
			return response()->json(['status'=>'success','code'=>200,'data'=>$dataFinal, 'totalRecord'=>1], 200);
		}else{
			return response()->json(['status'=>'failed','message'=>'failed get list percentage day, please try again later!','code'=>400], 400);
		}
	}


	public function getCalculateCurvaS(Request $request) // for adw (plan & actual == date)
	{
		$dataPayload = $request->all();
		$allGantt  = [];
		if(isset($dataPayload['gannt_id'])){
			$allGantt  = $dataPayload['gannt_id'];
		}else{
			foreach ($dataPayload['project_id'] as $val) {
				$allGantt[] = $this->getLatestGantt($val);
			}
		}
		$dataFinal=[];
		foreach ($allGantt as $keyGantt) {
			$dataProject = Project::find($keyGantt['proyek_id']);
			$dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['last_gantt_id'])->first();

			if($dataHeader){
				$totalRencanaBudget = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['last_gantt_id'])->sum("rencana_biaya");
			}else{
				$totalRencanaBudget = Activity::whereNull('parent_id')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['last_gantt_id'])->sum("rencana_biaya");

			}

			$minDate = DB::table('assign_material_to_activity as ama')
				->where("ama.proyek_id", $keyGantt['proyek_id'])
				->join('m_activity as a', 'a.id', '=', 'ama.activity_id')
				->where('a.version_gantt_id', '=', $keyGantt['last_gantt_id'])
				->min("plan_date");

			$maxDate = DB::table('assign_material_to_activity as ama')
				->where("ama.proyek_id", $keyGantt['proyek_id'])
				->join('m_activity as a', 'a.id', '=', 'ama.activity_id')
				->where('a.version_gantt_id', '=', $keyGantt['last_gantt_id'])
				->max("plan_date");

			$begin = new \DateTime($minDate);
			$end = new \DateTime($maxDate);
			$end2 = new \DateTime($maxDate);
			$interval = \DateInterval::createFromDateString('1 day');
			$period = new \DatePeriod($begin, $interval, $end);
			$arr_ActualM = [];
			$tempDate = [];
			$tempPercentage = [];
			$tempTtlPercentPlan=0;
			$tempTtlPercentActual=0;

			$currentACWP = 0;
			$budgetControlACWP = 0;
			$currentProgressActivity = 0;
			$currentBCWP = 0;
			$budgetControlBCWP = 0;

			foreach ($period as $dt) {
				$dataPlanM = DB::table('assign_material_to_activity as ama')
					->select('ama.activity_id', 'ama.qty_planning', 'ama.plan_date', 'ama.start_activity', 'a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress')
					->join('m_activity as a', 'a.id', '=', 'ama.activity_id')
					->where('ama.proyek_id', '=', $keyGantt['proyek_id'])
					->where('a.version_gantt_id', '=', $keyGantt['last_gantt_id'])
					->whereDate('ama.plan_date', $dt->format("Y-m-d"))
					->get();
				$dataActualM = DB::table('report_activity_material as ram')
					->select('ram.activity_id', 'ram.qty', 'ram.report_date', 'a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress')
					->join('m_activity as a', 'a.id', '=', 'ram.activity_id')
					->where('a.version_gantt_id', '=', $keyGantt['last_gantt_id'])
					->where('a.proyek_id', '=', $keyGantt['proyek_id'])
					->whereDate('ram.report_date', $dt->format("Y-m-d"))
					->get();
				$dataTempPlan = [];
				$x = 0;
				$sumPercentagePlan=0;
				$totalACWP = isset($totalACWP) ? $totalACWP : 0;
				$totalBCWP = isset($totalBCWP) ? $totalBCWP : 0;

				foreach ($dataPlanM as $keyPlanM) {
					$sumVolPlan = DB::table('assign_material_to_activity')
						->select('activity_id', DB::raw('SUM(qty_planning) as ttl_qty_plan'))
						->where('activity_id', '=', $keyPlanM->activity_id)
						->groupBy('activity_id')
						->first();
					$dataTempPlan [$x]['activity_id'] = $keyPlanM->activity_id;
					$dataTempPlan [$x]['qty_plan'] = $keyPlanM->qty_planning;
					$dataTempPlan [$x]['plan_date'] = $keyPlanM->plan_date;
					$dataTempPlan [$x]['start_activity'] = $keyPlanM->start_activity;
					$dataTempPlan [$x]['bobot_planning'] = $keyPlanM->bobot_planning;
					$dataTempPlan [$x]['ttl_plan'] = $sumVolPlan->ttl_qty_plan;
					$dataTempPlan [$x]['biaya_actual'] = $keyPlanM->biaya_actual;
					$dataTempPlan [$x]['duration'] = $keyPlanM->duration;
					$dataTempPlan [$x]['persentase_progress'] = $keyPlanM->persentase_progress;
					$dataTempPlan [$x]['percentage'] = ($keyPlanM->qty_planning/$sumVolPlan->ttl_qty_plan)*$keyPlanM->bobot_planning;
					$sumPercentagePlan+=($keyPlanM->qty_planning/$sumVolPlan->ttl_qty_plan)*$keyPlanM->bobot_planning;
					$totalBCWP += (((($keyPlanM->persentase_progress*$keyPlanM->bobot_planning)/100)/$keyPlanM->duration)* $totalRencanaBudget)/100;
					$dataTempPlan [$x]['totalBCWP'] = $totalBCWP;
					$x++;
				}

				$w = 0;
				$dataTempReport = [];
				$sumPercentageActual=0;
				foreach ($dataActualM as $keyActualM) {
					$sumVolActual = DB::table('assign_material_to_activity')
						->select('activity_id', DB::raw('SUM(qty_planning) as ttl_qty_plan'))
						->where('activity_id', '=', $keyActualM->activity_id)
						->groupBy('activity_id')
						->first();
					$dataTempReport [$w]['activity_id'] = $keyActualM->activity_id;
					$dataTempReport [$w]['qty'] = $keyActualM->qty;
					$dataTempReport [$w]['report_date'] = $keyActualM->report_date;
					$dataTempReport [$w]['bobot_planning'] = $keyActualM->bobot_planning;
					$dataTempReport [$w]['ttl_plan'] = $sumVolActual->ttl_qty_plan;
					$dataTempReport [$w]['biaya_actual'] = $keyActualM->biaya_actual;
					$dataTempReport [$w]['duration'] = $keyActualM->duration;
					$dataTempReport [$w]['persentase_progress'] = $keyActualM->persentase_progress;
					$dataTempReport [$w]['percentage'] = ($keyActualM->qty/$sumVolActual->ttl_qty_plan)*$keyActualM->bobot_planning;
					$sumPercentageActual+=($keyActualM->qty/$sumVolActual->ttl_qty_plan)*$keyActualM->bobot_planning;
					$totalACWP += $keyActualM->biaya_actual/$keyActualM->duration;
					$dataTempReport [$w]['totalacwp'] = $totalACWP;
					$w++;
				}

				$arr_ActualM[] = array(
					'date'=>$dt->format("Y-m-d"),
					'percentPlan'=>$sumPercentagePlan,
					'percentActual'=>$sumPercentageActual,
					'plan'=>$dataTempPlan,
					'actual'=>$dataTempReport,
				);
				if(isset($dataPayload['period']) && $dataPayload['period'] == 'week'){
					if($dt->format("w")==1){
						if($totalACWP > 0 ){
							$budgetControlACWP = $currentACWP + $totalACWP;
						}
						if($totalBCWP > 0 ){
							$budgetControlBCWP = $currentBCWP + $totalBCWP;
						}

						$tempTtlPercentPlan+= $sumPercentagePlan;
						$tempTtlPercentActual+= $sumPercentageActual;
						$currentACWP += $totalACWP;
						$currentBCWP += $totalBCWP;

						$tempPercentage[] = array(round($tempTtlPercentPlan,2), round($tempTtlPercentActual,2));
						$tempDate[] = array($dt->format("Y-m-d"), 0, 0);
					}else if($dt->format("Y-m-d") == $end2->format("Y-m-d")) {
						$tempTtlPercentPlan+= $sumPercentagePlan;
						$tempTtlPercentActual+= $sumPercentageActual;
						$currentACWP += $totalACWP;
						$currentBCWP += $totalBCWP;

						$tempPercentage[] = array(round($tempTtlPercentPlan,2), round($tempTtlPercentActual,2));
						$tempDate[] = array($dt->format("Y-m-d"), 0, 0);
						$tempTtlPercentPlan = 0;
						$tempTtlPercentActual = 0;
					}
				}else{
					$tempPercentage[] = array(round($sumPercentagePlan,2), round($sumPercentageActual,2));
					$tempDate[] = array($dt->format("Y-m-d"), 0, 0);
				}
			}

			if(round($totalACWP,0) > $totalRencanaBudget){
				$estimatedCost = round($totalACWP,0)+0;
			}else{
				$estimatedCost = ($totalRencanaBudget+0);
			}
			$costDeviation = $totalRencanaBudget - $estimatedCost;
			if($costDeviation > 0){
				$potential = "SAVING";
			} else {
				$potential = $costDeviation == 0 ? "ON BUDGET" : "OVERRUN";
			}

			$dataResponse = array(
				"date"              =>$tempDate,
				"percentage"        =>$tempPercentage,
				"data_details"      =>$arr_ActualM,
				"budget_control"    =>array("current_budget"=> $totalRencanaBudget,
				"acwp" => round($totalACWP,0),
				"bcwp" => round($totalBCWP,0),
				"rem_to_complete" => ($totalRencanaBudget - round($totalACWP,0)),
				"add_cost_to_complete" => 0,
				"estimated_at_completion" => $estimatedCost,
				"cost_deviation" => $costDeviation,
				"potential" => $potential,
				)
			);

			$dataFinal[] = array(
				"proyek_name"=> $dataProject->nama,
				"data"=>$dataResponse,
				"allGant"=>$allGantt
			);
		}

		return response()->json(['status'=>'success','code'=>200, 'data' => $dataFinal], 200);

	}

	public function getCalculateCurvaSDays(Request $request)
	{
		$dataPayload = $request->all();
		$allGantt  = [];
		foreach ($dataPayload['project_id'] as $val) {
			$allGantt[] = $this->getLatestGantt($val);
		}

		$dataFinal=[];
		foreach ($allGantt as $val) {
			$dataProject = Project::find($val['proyek_id']);
			$holidays = Holiday::where("version_gantt_id", $val['last_gantt_id'])->where("proyek_id", $val['proyek_id'])->get();
			$dateHoliday = []; //$holiday->all();
			foreach ($holidays as $holiday) {
				$startH = new \DateTime($holiday->date);
				$endH = clone $startH;
				$endH->modify('+'.$holiday->duration.' day');
				$intervalH = \DateInterval::createFromDateString('1 day');
				$periodH = new \DatePeriod($startH, $intervalH, $endH);
				foreach ($periodH as $dt) {
					$dateHoliday[] = $dt->format("Y-m-d");
				}
			}
			$verGantt = VersionGantt::find($val['last_gantt_id']);
			$configOff = $verGantt->config_dayoff;
			if($configOff && $configOff!= ""){
				$dayOff = explode(",", $verGantt->config_dayoff);
				$dayOff = array_map(
					function($value) { return (int)$value; },
						$dayOff
				);
			}else{
				$dayOff = [];
			}
			$dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->first();
			if($dataHeader){
				$minDate = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->min("start_date");
				$maxDate = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->max("end_date");
			}else{
				$minDate = Activity::whereNull('parent_id')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->min("start_date");
				$maxDate = Activity::whereNull('parent_id')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->max("end_date");
			}

			$begin = new \DateTime($minDate);
			$end = new \DateTime($maxDate);
			$interval = \DateInterval::createFromDateString('1 day');
			$period = new \DatePeriod($begin, $interval, $end);
			$dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->first();
			if($dataHeader){
				$totalRencanaBudget = Activity::select(DB::raw('sum(cast(rencana_biaya as integer))'))->where('parent_id', $dataHeader->id)->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->first();
			}else{
				$totalRencanaBudget = Activity::select(DB::raw('sum(cast(rencana_biaya as integer))'))->whereNull('parent_id')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->first();
			}

			$totalRencanaBudget = $totalRencanaBudget->sum;
			$currentPercentage = 0;
			$currentACWP = 0;
			$currentProgressActivity = 0;
			$currentBCWP = 0;
			$dataDate = [];
			$dataPercen = [];
			$testdata = [];
			foreach ($period as $dt) {
				$weekDay = $dt->format("w");
				$currentDate = $dt->format("Y-m-d");
				$testdata[] = array('weekday' => $weekDay, 'date' =>$currentDate);
				if(!in_array($weekDay, $dayOff) && !in_array($currentDate, $dateHoliday))
				{
					$totalPercentage = 0;
					$totalACWP = 0;
					$totalProgressActivity = 0;
					$totalBCWP = 0;
					$dataActivity = Activity::whereRaw("'".$currentDate."' BETWEEN DATE(m_activity.start_date) AND DATE(m_activity.end_date) - INTERVAL '1 DAY'")->where('type_activity', 'task')->where("proyek_id", $val['proyek_id'])->where("version_gantt_id", $val['last_gantt_id'])->get();
					foreach ($dataActivity as $activity) {

						$duration = $activity->duration;
						if($totalRencanaBudget > 0 && $duration > 0){
							$totalPercentage += $activity->bobot_planning/$duration;
							if($activity->biaya_actual > 0 && $activity->persentase_progress){
								$totalACWP += $activity->biaya_actual/$duration;
								$totalProgressActivity += (($activity->persentase_progress*$activity->bobot_planning)/100)/$duration;
								$totalBCWP += (((($activity->persentase_progress*$activity->bobot_planning)/100)/$duration)* $totalRencanaBudget)/100;
							}
						}
					}

					$currentPercentage = round(($currentPercentage + $totalPercentage), 0);
					$currentACWP = $totalACWP == 0 ? null : $currentACWP + $totalACWP;
					$currentProgressActivity = $totalProgressActivity == 0 ? null : round(($currentProgressActivity + $totalProgressActivity),0);
					$currentBCWP = $totalBCWP == 0 ? null :$currentBCWP + $totalBCWP;
					$currentPercentage = $currentPercentage > 100 ? 100 : $currentPercentage;
					$currentProgressActivity = $currentProgressActivity > 100 ? 100 : $currentProgressActivity;


					$dataDate[] = array($currentDate, $currentBCWP, $currentACWP);
					$dataPercen[] = array($currentPercentage, $currentProgressActivity);
				}else{
					$dataDate[] = $currentDate;
					$dataPercen[] = array($currentPercentage,$currentProgressActivity);
				}
			}
			$dataPercentage = array(
				"date"=>$dataDate,
				"percentage"=>$dataPercen
			);
			$dataFinal[] = array(
				"proyek_name"=> $dataProject->nama,
				"data"=>$dataPercentage
			);
		}

		if($dataFinal){
			return response()->json(['status'=>'success','code'=>200,'data'=>$dataFinal, 'testdata' => $testdata, '$period' => $period, 'totalRecord'=>1], 200);
		}else{
			return response()->json(['status'=>'failed','message'=>'failed get list percentage day, please try again later!','code'=>400], 400);
		}
	}

	private function getLatestGantt($id){
		return array(
			"last_gantt_id" => VersionGantt::where("proyek_id", $id)->latest(),
			"proyek_id" => $id
		);
	}

	public function setBaseline($gantt_id)
	{
		$activities = Activity::where("version_gantt_id", $gantt_id)->get();

		foreach ($activities as $activity) {
			$activity->update([
				"planned_start"=>$activity->start_date,
				"planned_end"=>$activity->end_date,
			]);
		}

		return response()->json(['status'=>'success','message'=>'Set baseline success!','code'=> 200], 200);
	}

	public function synchronizeReport($gantt_id)
	{
		$activities = Activity::where("version_gantt_id", $gantt_id)->get();
		$reports = [];

		foreach($activities as $activity) {
			$activity_id = $activity->id;
			$countReports = ReportActivity::where('activity_id', $activity_id)->count();
			if ($countReports === 1) {
				$dataReports = ReportActivity::where('activity_id', $activity_id)->orderBy('report_date')->get();
				foreach($dataReports as $dr) {
					$reports[] = array(
						'activity_id'=>$activity_id,
						'min_date'=>$dr->report_date,
						'max_date'=>date_modify(date_create($dr->report_date), "1 days")
					);
				}
			}
			if ($countReports > 1) {
				$firstReport = ReportActivity::where('activity_id', $activity_id)->orderBy('report_date')->first();
				$lastReport = ReportActivity::where('activity_id', $activity_id)->orderByDesc('report_date')->first();
				$reports[] = array(
					'activity_id'=>$activity_id,
					'min_date'=>$firstReport->report_date,
					'max_date'=>date_modify(date_create($lastReport->report_date), "1 days")
				);

			}
		}

		for ($i=0; $i < count($reports); $i++) {
			$activity = Activity::find($reports[$i]['activity_id']);
			$activity->start_date = $reports[$i]['min_date'];
			$activity->end_date = $reports[$i]['max_date'];
			$activity->save();
		}

		return response()->json(['status'=>'success','message'=>'Synchronize to report success!','code'=>200], 200);
	}
}