<?php

namespace App\Models;

use App\Models\AssignMaterial;
use App\Models\AssignTools;
use App\Models\ReportActivityMaterial;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;

class Activity extends Model
{
    protected $table = 'm_activity';

    const CREATED_AT = 'created_at';
    const UPDATED_AT = 'updated_at';

    protected $fillable = [
        'proyek_id', 'parent_id', 'kode_sortname', 'name', 'rencana_biaya', 'start_date',
        'end_date', 'area_kerja', 'biaya_actual', 'persentase_bobot', 'persentase_progress',
        'buffer_radius', 'duration', 'color_progress', 'jumlah_pekerjaan', 'satuan',
        'description', 'priority', 'bobot_planning', 'type_activity', 'open', 'geom',
        'version_gantt_id', 'budget_plan', 'biaya_material_plan', 'biaya_human_plan', 'biaya_tools_plan',
        'planned_start', 'planned_end', 'satuan_id',
        'created_at', 'created_by', 'updated_at', 'updated_by'
    ];
	// this piece of shit prepend column on create(), causing bugs
	//protected $attributes = [
	//	'jobs_done', 'assign_hr', 'assign_material', 'assign_tools'
	//];

	protected $appends = [
		'jobs_done', 'assign_hr', 'assign_material', 'assign_tools'
	];

	public static function boot() {
		parent::boot();

		static::updated(function($data) {
			$data->updateBobot();
			$data->updateCostPlanning();
			$data->updatePersentaseProgress();
			$data->updateCostActual();
		});

		static::deleted(function($data) {
			if(Activity::where("parent_id", $data->parent_id)->count() == 0)
				Activity::find($data->parent_id)->update(["type_activity"=>"task"]);

			$data->updateCostPlanning();
			$data->updatePersentaseProgress();
			$data->updateCostActual();
		});

	}

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


		if($totalCost->sum > 0){
			$activities = Activity::where("proyek_id", $this->proyek_id)->where("version_gantt_id", $this->version_gantt_id)->get();
			foreach ($activities as $activity) {
				$activity->update([
					"bobot_planning" => ( (int)$activity->rencana_biaya / $totalCost->sum ) * 100,
					"updated_by" => auth()->user() ? auth()->user()->name : "system",
				]);
				$activity->save();
			}
		}
	}

	private function updateCostActual()
	{
		$actualCost = Activity::where("parent_id", $this->parent_id)->sum("biaya_actual");
		$this->biaya_actual = $actualCost;
		if($parent = Activity::find($this->parent_id)){
			$parent->update([
				"biaya_actual" => $actualCost
			]);
		}
	}

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

		$this->persentage_progress = $sumProgress / $totalChild;
		if($parent = Activity::find($this->parent_id)){
			$parent->update([
				"persentase_progress" => $sumProgress / $totalChild,
			]);
		}
	}

	private function updateCostPlanning() {
		$sumBiaya = Activity::select(DB::raw('sum(cast(rencana_biaya as double precision))'))
			->where("parent_id", $this->parent_id)
			->first();
		$this->rencana_biaya = $sumBiaya->sum;
		if($parent = Activity::find($this->parent_id)){
			$parent->update([
				"rencana_biaya" => $sumBiaya->sum,
			]);
		}
	}

	public function getJobsDoneAttribute()
	{
		$tmpPercentage = [];
        if(!ReportActivityMaterial::where('activity_id', $this->id)->first()) 
                return 0; 
        if(!$dataPlan = AssignMaterial::where('activity_id', $this->id)->get()) 
                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;
	}

	public function getAssignHrAttribute()
	{
		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', $this->id)
			->get()
			->toArray());
	}

	public function getAssignMaterialAttribute()
	{
		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', $this->id)
			->get()
			->toArray());
	}

	public function getAssignToolsAttribute()
	{
		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', $this->id)
			->get()
			->toArray());
	}

}