<?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\AnalyticLeadListYearDTO;

use App\Modules\Analytics\Sales\Application\Reports\AnalyticLeadReport;


class AnalyticLeadListYearController extends Controller
{
	private $oDomain;


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


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


		//------------------------------------------------------------------------------
		//	VARIABLES
		//------------------------------------------------------------------------------
		$pDate_Year		= json_decode($oDTO->DateYear, true);
		$pDate_Month	= json_decode($oDTO->DateMonth, true);
		$pExport		= $oDTO->Export;
		// $pOrder			= "";

		// switch( $oDTO->Order )
		// {
		// 	case "SALE" 		: $pOrder = ""; break;
		// 	case "BOOKING" 		: $pOrder = ""; break;
		// 	case "PASSENGER" 	: $pOrder = ""; break;
		// 	default				: $pOrder = ""; break;
		// }


		// 0: DELETED
		// 1: NEW
		// 2: PRE_BOOKING
		// 3: CONFIRMED
		// 4: CANCELED
		// 5: ASSOCIATED
        // 6: ASSIGNED
		// 7: ANSWERED
		// 8: LOST
		// 9: HOLD
		// 10: RECOVERED


		//------------------------------------------------------------------------------
		//	FUNCTION
		//------------------------------------------------------------------------------
		$oSubQuery	= DB::query();
		$oSubQuery->from('v_leads');
		$oSubQuery->selectRaw("
			Lead_Date_Year AS Year,
			Lead_Date_Month AS Month,
			COUNT(*) AS Total_Received,
			SUM(CASE WHEN Lead_Status = 3 THEN 1 ELSE 0 END) AS Total_Converted,
			SUM(CASE WHEN Lead_Status = 8 THEN 1 ELSE 0 END) AS Total_Lost
		");
		$oSubQuery->whereIn("Lead_Date_Year", $pDate_Year);
		$oSubQuery->whereIn("Lead_Date_Month", $pDate_Month);
    	$oSubQuery->groupBy("Lead_Date_Year");
		$oSubQuery->groupBy("Lead_Date_Month");


		$oQuery = DB::query();

		$oQuery->fromSub($oSubQuery, "m");
    	$oQuery->selectRaw("
			fn_month_name_get(Month, 'SHORT') AS Label,
			fn_month_name_get(Month, 'FULL') AS Title,
			Year,
			Month,

			IFNULL(Total_Received, 0) AS Total_Received,
			IFNULL(Total_Converted, 0) AS Total_Converted,
			IFNULL(Total_Lost, 0) AS Total_Lost,

			CASE
				WHEN IFNULL(LAG(Total_Received) OVER (PARTITION BY Year ORDER BY Month), 0) = 0
				THEN 0
				ELSE
					(Total_Received - LAG(Total_Received) OVER (PARTITION BY Year ORDER BY Month) ) / LAG(Total_Received) OVER (PARTITION BY Year ORDER BY Month )
			END AS MoM_Received,
			CASE
				WHEN IFNULL(LAG(Total_Converted) OVER (PARTITION BY Year ORDER BY Month), 0) = 0
				THEN 0
				ELSE
					(Total_Converted - LAG(Total_Converted) OVER (PARTITION BY Year ORDER BY Month) ) / LAG(Total_Converted) OVER (PARTITION BY Year ORDER BY Month )
			END AS MoM_Converted,
			CASE
				WHEN IFNULL(LAG(Total_Lost) OVER (PARTITION BY Year ORDER BY Month), 0) = 0
				THEN 0
				ELSE
					(Total_Lost - LAG(Total_Lost) OVER (PARTITION BY Year ORDER BY Month) ) / LAG(Total_Lost) OVER (PARTITION BY Year ORDER BY Month )
			END AS MoM_Lost,

			CASE
        		WHEN Total_Received = 0 THEN 0
        		ELSE (Total_Converted / Total_Received)
    		END AS Rate_Conversion
		");
    	$oQuery->orderBy("Year", "DESC");
		$oQuery->orderBy("Month", "ASC");

		$oData = $oQuery->get();


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

										return [
											"Label"				=> $oRow->Label ?? "",
											"Title"				=> $oRow->Title ?? "",
											"Month"      		=> $Month,
											"Total_Received" 	=> $oRow->Total_Received ?? 0,
											"Total_Converted"	=> $oRow->Total_Converted ?? 0,
											"Total_Lost"		=> $oRow->Total_Lost ?? 0,
											"MoM_Received"		=> $oRow->MoM_Received ?? 0,
											"MoM_Converted"		=> $oRow->MoM_Converted ?? 0,
											"MoM_Lost"			=> $oRow->MoM_Lost ?? 0,
											"Rate_Conversion"	=> $oRow->Rate_Conversion ?? 0
										];
									})->values()
								];
							})
							->values();


		//------------------------------------------------------------------------------
		//	RESPONSE
		//------------------------------------------------------------------------------
		if ( $pExport == false )
		{
			$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);
		}
		else
		{
			AnalyticLeadReport::Report_Comparative($oData->toArray());
		}

    }


}