<?php

namespace App\Services\Reports;

use Carbon\Carbon;
use App\Repositories\Reports\AssetRecoveryRepository;
use App\Repositories\CommonFilterRepository;
use App\Http\Responses\ReportOutputData;

class AssetRecoveryService  extends AbstractReportService
{
    protected $repository;
    protected $commonFilterRepository;
    protected $reportOutputData;

    /**
     * __construct
     *
     * @param  AssetRecoveryRepository $repository
     * @param CommonFilterRepository $commonFilterRepository The commonFilterRepository instance.
     * @param ReportOutputData $reportOutputData The reportOutputData instance
     *
     * @return void
     */
    public function __construct(AssetRecoveryRepository $repository, CommonFilterRepository $commonFilterRepository, ReportOutputData $reportOutputData)
    {
        $this->repository = $repository;
        $this->commonFilterRepository = $commonFilterRepository;
        $this->reportOutputData = $reportOutputData;
    }

    /**
     * Fetching report data
     *
     * @return data
     */
    public function data()
    {
        $inputData  = $this->getInputData();
        $assets = $this->repository->getReturnedAssetsFromTerminatedUsers();
        $assets = $this->filterResults($assets, $inputData);
        $count = $assets->get()->count();
        $assets = $this->reportOutputData->getOutputData($assets, ['id' => 'desc']);

        return compact('assets', 'count');
    }

    /**
     * Checking and organising filter input data
     * */
    public function getInputData()
    {
        $requestedData = request()->form ?? request()->all();

        $inputData =  [
            'search_date_from'    => $requestedData['search_date_from'] ?? '',
            'search_date_to' => $requestedData['search_date_to'] ?? '',
        ];

        return $inputData;
    }

    /**
     * Filters the results based on the input data.
     *
     * @param array $assets The array of assets to filter.
     * @param array $inputData The input data used for filtering.
     * @return object The filtered array of assets.
     */
    public function filterResults($assets, $inputData)
    {
        $assets = $this->commonFilterRepository->filterWithRelationalDateRange($assets, 'oldUser', 'terminated_date', $inputData['search_date_from'], $inputData['search_date_to']);

        return $assets;
    }

    /**
     * Returns an array of nested data for exporting.
     *
     * @param mixed $asset The asset object.
     * @return array The nested data array.
     */
    public function getReportNestedData($asset)
    {
        $nestedData['report']['asset_tag']  = $nestedData['export']['Asset Tag #'] = disableCSVInjection(optional($asset->asset)->asset_tag);
        $nestedData['report']['serial_no'] = $nestedData['export']['Serial #']  = disableCSVInjection(optional($asset->asset)->serial_no);
        $nestedData['report']['asset_type'] = $nestedData['export']['Asset Type']   = disableCSVInjection(optional(optional($asset->asset)->assetType)->name);
        $nestedData['report']['hardware_standard'] = $nestedData['export']['Hardware Standard'] = disableCSVInjection(optional(optional($asset->asset)->makeAndModel)->name);
        $nestedData['report']['tech_specs'] = $nestedData['export']['Technical Specs'] = disableCSVInjection(optional(optional($asset->asset)->technicalSpec)->details);
        $nestedData['report']['date_it_storage'] = $nestedData['export']['Date On Hand'] = disableCSVInjection($asset->created_at ? Carbon::parse($asset->created_at)->format('m/d/Y') : '');
        $nestedData['report']['old_status'] = $nestedData['export']['Previous Status'] = disableCSVInjection(optional($asset->oldStatus)->name);
        $nestedData['report']['date_status_changed'] = $nestedData['export']['Date Deployed'] = disableCSVInjection($asset->redeployedDate ? Carbon::parse($asset->redeployedDate)->format('m/d/Y') : '');
        $nestedData['report']['new_status'] = $nestedData['export']['Current Status'] = disableCSVInjection(optional(optional($asset->asset)->assetStatus)->name);
        $depreciatedValue = optional($asset->asset)->depreciatedValue ?? 0;
        $nestedData['report']['depreciated_value']  = $nestedData['export']['Asset Depreciated Value']  = config('currency.currency_symbol') . number_format($depreciatedValue);

        return $nestedData;
    }

    /**
     * Generating data table data from qurey result
     * @param $assets Query Result
     * @param $index  index
     * */
    public function getNestedData($assetHistory, $index)
    {
        $commonData = $this->getReportNestedData($assetHistory);
        $nestedData = $commonData['report'];
        $nestedData['id']   = $index;
        $nestedData['asset_tag'] = generateAssetLink($assetHistory->asset?->id, $assetHistory->asset?->asset_tag);
        $nestedData['serial_no'] = generateAssetLink($assetHistory->asset?->id, $assetHistory->asset?->serial_no);

        return $nestedData;
    }

    /**
     * Retrieves the export data based on the input data.
     *
     * @return mixed The export data.
     */
    public function exportData()
    {
        $inputData  = $this->getInputData();
        $assets = $this->repository->getReturnedAssetsFromTerminatedUsers();
        $assets = $this->filterResults($assets, $inputData);
        $assets = $assets->orderBy('id');

        return $assets;
    }

    /**
     * Generating data for the graph
     * */
    public function getGraphData()
    {
        $inputData  = $this->getInputData();
        $assets = $this->repository->getReturnedAndRedeployedAssetsCount();
        $assets = $this->filterResults($assets, $inputData);
        $assets = $assets->get();
        $TotalReturnedCount =  $assets->sum('asset_count') ?? 0;
        $redeployedCount =  $assets->sum('redeployedAssetCount') ?? 0;
        $returnedCount = $TotalReturnedCount - $redeployedCount;

        $graphData[] = ['label' => ['Returned'], 'value' => [$returnedCount]];
        $graphData[] = ['label' => ['Redeployed'], 'value' => [$redeployedCount]];

        return $graphData;
    }
}
