<?php

namespace App\Services\Terminations\HrCollection;

use App\Repositories\Reports\RetrievalStatisticsWidgetRepository;
use Carbon\Carbon;

class RetrievalStatisticsReportWidgetService
{
    protected $repository;

    /**
     * Constructor for the class.
     *
     * @param RetrievalStatisticsWidgetRepository $repository The repository object for the retrieval statistics widget.
     */
    public function __construct(RetrievalStatisticsWidgetRepository $repository)
    {
        $this->repository = $repository;
    }

    /**
     * Retrieves the widget data based on the input parameters.
     *
     * @return array Returns an array containing the terminations count, assets assigned count, assets returned count, assets unrecoverable count, and assets pending count.
     */
    public function getWidgetData()
    {
        $inputData = request()->all();
        $widgetFilterDays = $inputData['widget_filter'] ?? 30;
        $endDate = Carbon::now()->format(config('date.formats.read_date_format'));
        $startDate = Carbon::now()->subDays($widgetFilterDays)->format(config('date.formats.read_date_format'));

        $terminationsCount = $this->repository->getTerminationsCount($startDate, $endDate);
        $assetsAssignedCount = $this->repository->getAssetsAssignedCount($startDate, $endDate);
        $assetsReturnedCount = $this->repository->getAssetsReturnedCount($startDate, $endDate);
        $assetsUnrecoverableCount = $this->repository->getAssetsUnrecoverableCount($startDate, $endDate);
        $averageReturnTime = $this->getAverageReturnTime($startDate, $endDate);
        $assetsPendingCount = $assetsAssignedCount - $assetsReturnedCount;

        return compact('terminationsCount', 'assetsAssignedCount', 'assetsReturnedCount', 'assetsUnrecoverableCount', 'assetsPendingCount', 'averageReturnTime');
    }

    /**
     * Calculates the average return time for assets within a given date range.
     *
     * @param mixed $startDate The start date of the range.
     * @param mixed $endDate The end date of the range.
     * @return float The average return time in days.
     */
    public function getAverageReturnTime($startDate, $endDate)
    {
        $assetsComingBackQuery = $this->repository->getComingBackAssets($startDate, $endDate);
        $assetsComingBack = $assetsComingBackQuery->get();
        $assetsComingBackCount = $assetsComingBackQuery->count();
        $noOfDays = 0;

        foreach ($assetsComingBack as $assetHistory) {
            $nextStatusAfterAssigned = $this->repository->getNextStatusAfterAssigned($assetHistory->asset_id, $assetHistory->newUser?->id);

            if (!empty($assetHistory?->newUser?->terminated_date) && !empty($nextStatusAfterAssigned)) {
                $noOfDays += Carbon::parse($nextStatusAfterAssigned->getRawOriginal('created_at'))->diffInDays($assetHistory?->newUser?->getRawOriginal('terminated_date'));
            }
        }

        if ($noOfDays && $assetsComingBackCount) {
            return $noOfDays / $assetsComingBackCount;
        }

        return 0;
    }
}
