<?php

namespace App\Http\Controllers\Owner\Analytic;

use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Helpers\ResponseBuilder;
use App\Modules\Shared\Validator\Infraestructure\LaravelDTOGenerator;
use App\Http\Controllers\Owner\Analytic\Dto\AnalyticBookingListYearDTO;


class AnalyticBookingListYearController extends Controller
{
	private $oDomain;


	public function __construct
	(
		private LaravelDTOGenerator $oLaravelDTOGenerator
	)
	{
        $this->oDomain = "Analytic Booking List Year";
    }


	public function __invoke(Request $request)
    {
		//------------------------------------------------------------------------------
		//	VALIDATE
		//------------------------------------------------------------------------------
		$oDTO = $this->oLaravelDTOGenerator->generate($request->all(), $this->oDomain, AnalyticBookingListYearDTO::class);


		//------------------------------------------------------------------------------
		//	VARIABLES
		//------------------------------------------------------------------------------
		$pYear	= date("Y");
		$pYears	= [($pYear - 2), ($pYear - 1), $pYear];
		$pType	= $oDTO->Type;		// CONFIRM - TOUR


		$pQuery_Select		= "";
		$pQuery_WhereIn		= [];
		$pQuery_GroupBy		= "";
		$pQuery_OrderBy		= "";


		//------------------------------------------------------------------------------
		//	FUNCTION
		//------------------------------------------------------------------------------
		if ($pType == "CONFIRM")
		{
			$pQuery_Select		= "Booking_Confirm_Year AS Year, Booking_Confirm_Month AS Month, COUNT(DISTINCT Id_Booking) AS Total_Booking, IFNULL(SUM(CashMovementDetail_Amount), 0) AS Total_Sale";
			$pQuery_WhereIn		= [ [ "Booking_Confirm_Year", $pYears ] ];
			$pQuery_GroupBy 	= [ "Booking_Confirm_Year", "Booking_Confirm_Month" ];
			$pQuery_OrderBy		= [ [ "Booking_Confirm_Year", "DESC" ], [ "Booking_Confirm_Month", "ASC" ] ];
		}
		else if ($pType == "TOUR")
		{
			$pQuery_Select		= "Booking_Start_Year AS Year, Booking_Start_Month AS Month, COUNT(DISTINCT Id_Booking) AS Total_Booking, IFNULL(SUM(CashMovementDetail_Amount), 0) AS Total_Sale";
			$pQuery_WhereIn		= [ [ "Booking_Start_Year", $pYears ] ];
			$pQuery_GroupBy 	= [ "Booking_Start_Year", "Booking_Start_Month" ];
			$pQuery_OrderBy		= [ [ "Booking_Start_Year", "DESC" ], [ "Booking_Start_Month", "ASC" ] ];
		}

		//------------------------------------------------------------------------------
		//	QUERY
		//------------------------------------------------------------------------------
		$oQuery = DB::query();

		$oQuery->from('v_booking_sales');
    	$oQuery->selectRaw($pQuery_Select);
    	foreach ($pQuery_WhereIn as $oItem)
		{
			$oQuery->whereIn($oItem[0], $oItem[1]);
		}
		foreach ($pQuery_GroupBy as $oItem)
		{
			$oQuery->groupBy($oItem);
		}
		foreach ($pQuery_OrderBy as $oItem)
		{
			$oQuery->orderBy($oItem[0], $oItem[1]);
		}

		$oData = $oQuery->get();


		//------------------------------------------------------------------------------
		//	MAP
		//------------------------------------------------------------------------------
		$oMonths	= collect(range(1, 12));
		$oData 		= $oData->groupBy("Year")
							->map(function ($oItems, $Year) use ($oMonths)
							{
								return [
									"Year" 		=> $Year,
									"Months"	=> $oMonths->map(function ($Month) use ($oItems)
									{
										$oRow = $oItems->firstWhere('Month', $Month);

										return [
											"Month"      	=> $Month,
											"Total_Booking"	=> $oRow->Total_Booking ?? 0,
											"Total_Sale" 	=> $oRow->Total_Sale ?? 0
										];
									})->values()
								];
							})
							->values();


		//------------------------------------------------------------------------------
		//	RESPONSE
		//------------------------------------------------------------------------------
		$oResponse["Response_Status"]           = 200;
		$oResponse["Response_Code"]             = 200;
		$oResponse["Response_Domain"]           = $this->oDomain;
		$oResponse["Response_Message"]          = $this->oDomain . " List";
		$oResponse["Response_Data"]             = $oData;
		$oResponse["Response_Error_Message"]    = "";
		$oResponse["Response_Error_Reason"]     = "";

		return ResponseBuilder::Response($oResponse);

    }


}