<?php

namespace App\Services\Reports;

use App\Repositories\Reports\AssetRecoveryValueRepository;
use App\Repositories\CommonFilterRepository;
use App\Http\Responses\ReportOutputData;
use App\Http\Traits\DepreciationValueTrait;
use Carbon\Carbon;

/**
 * Service class for Asset Recovery Value Report
 */
class AssetRecoveryValueService extends AbstractReportService
{
    use DepreciationValueTrait;

    protected $repository;
    protected $commonFilterRepository;
    protected $reportOutputData;

    /**
     * Construct of AssetRecoveryValueService
     * @param AssetRecoveryValueRepository $repository The repository for the InStockComputer Repository entity
     * @param CommonFilterRepository $commonFilterRepository The repository for the CommonFilter entity
     * @param ReportOutputData $reportOutputData The ReportOutputData entity
     */
    public function __construct(AssetRecoveryValueRepository $repository, CommonFilterRepository $commonFilterRepository, ReportOutputData $reportOutputData)
    {
        $this->repository = $repository;
        $this->commonFilterRepository = $commonFilterRepository;
        $this->reportOutputData = $reportOutputData;
    }

    /**
     * Data to the Report data table
     *
     * @return void
     */
    public function data()
    {
        $result = $this->repository->getRecoveryAssets();
        $result = $this->filterWithInputData($result);
        $count  = $result->count();
        $result = $this->reportOutputData->getOutputData($result, ['id' => 'asc']);

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

    /**
     * Filter the query results based on the filters applied
     *
     * @param  mixed $assets
     * @return object
     */
    public function filterWithInputData($assets)
    {
        $requestedData = request()->form ? request()->form : request()->all();
        $requestedData['asset_age'] = Carbon::now()->subYears($requestedData['asset_age'])->format(config('date.formats.read_date_format'));
        $assets = $this->commonFilterRepository->filterWithDirectFields($assets, 'assets.asset_type_id', $requestedData['asset_type'] ?? '');
        $assets = $this->commonFilterRepository->filterWithDirectFields($assets, 'assets.make_and_model_id', $requestedData['make_and_model'] ?? '');
        $assets = $this->commonFilterRepository->filterWithDirectFields($assets, 'asset_status_id', $requestedData['status'] ?? '');
        $assets = $this->commonFilterRepository->filterWithDirectFields($assets, 'location_id', $requestedData['location'] ?? '');
        $assets = $this->commonFilterRepository->filterWithWhereHasRelationFields($assets, 'makeAndModel.manufacturer', 'id', $requestedData['manufacturer'] ?? '');
        $assets = $this->commonFilterRepository->filterWithDirectDateRange($assets, 'assets.created_at', null, $requestedData['asset_age'] ?? '');

        return $assets;
    }

    /**
     * export Data as csv
     *
     * @return mixed
     */
    public function exportData()
    {
        $assets  = $this->repository->getRecoveryAssets();
        $assets  = $this->filterWithInputData($assets);
        $assets  = $assets->orderBy('id');

        return $assets;
    }


    /**
     * get Report and export common Nested Data
     *
     * @param  mixed $history
     * @return void
     */
    public function getReportNestedData($asset)
    {

        $nestedData['report']['asset_tag'] = $nestedData['export']['Asset Tag #'] = $asset->asset_tag;
        $nestedData['report']['serial_number'] = $nestedData['export']['Serial #'] = $asset->serial_no;
        $nestedData['report']['type'] = $nestedData['export']['Asset Type'] = $asset->assetType ? $asset->assetType->name : '';
        $nestedData['report']['manufacturer'] = $nestedData['export']['Manufacturer'] = optional(optional($asset->makeAndModel)->manufacturer)->name;
        $nestedData['report']['hardware_standard'] = $nestedData['export']['Hardware Standard'] = optional($asset->makeAndModel)->name;
        $nestedData['report']['asset_status'] = $nestedData['export']['Asset Status'] = $asset->assetStatus ? $asset->assetStatus->name : '';

        $nestedData['report']['user_location'] = $nestedData['export']['User/Location'] = $asset->user ? ($asset->user?->user_name) : ($asset->location ? $asset->location->room_name : '');
        if ($asset->user && $asset->location) {
            $nestedData['report']['user_location'] = $nestedData['export']['User/Location'] = ($asset->user?->first_name . ' ' . $asset->user?->last_name) . ' / ' . $asset->location->room_name;
        }

        $nestedData['report']['created_at'] = $nestedData['export']['Created Date'] = $asset->created_at;
        $nestedData['report']['age'] = $nestedData['export']['Asset Age'] = $asset->AssetAge;
        $nestedData['report']['depreciated_value'] = $nestedData['export']['Depreciated Value'] = config('currency.currency_symbol') . number_format($asset->depreciatedValue);
        $nestedData['report']['warranty_end_date'] = $nestedData['export']['Warranty End Date'] = $asset->warranty_end_date;

        return $nestedData;
    }

    /**
     * nested data for report
     *
     * @return array
     */
    public function getNestedData($asset, $index)
    {
        $nestedData = [];
        $assetTagLink = route('assets.show', $asset->id);
        $commonData = $this->getReportNestedData($asset);
        $nestedData = $commonData['report'];
        $nestedData['id']   = $index;
        $nestedData['asset_tag'] = generateAssetLink($asset->id, $asset->asset_tag);
        $nestedData['serial_number'] = generateAssetLink($asset->id, $asset->serial_no);

        $userAndLocation = '';
        if ($asset->user) {
            $userAndLocation = generateUserLink($asset->user?->id, $asset->user?->user_name);
        }

        if ($asset->location) {
            $userAndLocation = generateLocationLink($asset->location->id, $asset->location->room_name);
        }

        if ($asset->user && $asset->location) {
            $userAndLocation .= ' / ' . generateLocationLink($asset->location->id, $asset->location->room_name);
        }
        $nestedData['user_location'] = $userAndLocation;

        return $nestedData;
    }

    /**
     * Get widget counts
     *
     * @return [type]
     */
    public function getWidgetCountData()
    {
        $assets = $this->repository->getRecoveryAssets();
        if (request()->ajax()) {
            $assets = $this->filterWithInputData($assets);
        }

        $count['asset_depreciation_value'] = config('currency.currency_symbol'). number_format($this->getDepreciationValue($assets));
        return $count;
    }
}
