<?php

namespace App\Services\Api;

use App\Http\Requests\Api\GetAssetRequest;
use Illuminate\Http\Request;
use App\Repositories\Api\SearchAssetRepository;
use App\Http\Resources\Asset\AssetCollection;
use App\Http\Resources\Asset\TerminatedAssetCollection;

class SearchAssetService extends ApiService
{
    /**
     * @var SearchAssetRepository
     */
    protected $searchAssetRepository;

    /**
     * Create a new SearchAssetService instance.
     *
     * @param SearchAssetRepository $searchAssetRepository
     */
    public function __construct(SearchAssetRepository $searchAssetRepository)
    {
        $this->searchAssetRepository = $searchAssetRepository;
    }

    /**
     * Carries out the general search of assets.
     *
     * @param Request $request The HTTP request object.
     *
     * @return AssetCollection
     */
    public function searchAssets(Request $request)
    {
        $assets = $this->searchAssetRepository->getJoinedAssetQuery();
        $assets = $this->searchAssetRepository->searchAssetsWithGeneralQueries($assets, $request->search);

        $limit     = $this->getQueryLimit($request->limit);

        return new AssetCollection($assets->paginate($limit));
    }

    /**
     * Gets all assets with pagination and optional filtering.
     *
     * @param GetAssetRequest $request The HTTP request object.
     *
     * @return AssetCollection
     */
    public function getAssets(Request $request)
    {
        $assets = $this->searchAssetRepository->getJoinedAssetQuery();
        $assets = $this->filterAssets($request, $assets);
        $limit     = $this->getQueryLimit($request->limit);

        return new AssetCollection($assets->paginate($limit));
    }

    /**
     * Filter assets based on optional inputs.
     *
     * @param GetAssetRequest $request The HTTP request object.
     * @param mixed $assets The query builder instance for assets.
     *
     * @return mixed
     */
    public function filterAssets(GetAssetRequest $request, $assets)
    {
        foreach (config('api-filter-fields.assets.filter_fields') as $key) {
            if ($request->has($key)) {
                $assets = $this->searchAssetRepository->filterByDirectFields($assets, $request->$key, $key);
            }
        }

        foreach (config('api-filter-fields.assets.relational_filter_fields') as $key => $value) {
            if ($request->has($key)) {
                $assets = $this->searchAssetRepository->filterByRelatedModelFields($assets, $request->$key, $value['relation'], $value['db_field']);
            }
        }

        foreach (config('api-filter-fields.assets.filter_date_fields') as $key => $value) {
            if ($request->has($key)) {
                $assets = $this->searchAssetRepository->filterByDateFields($assets, $request->$key, $value['db_field']);
            }
        }

        foreach (config('api-filter-fields.assets.relational_date_fields') as $key => $value) {
            if ($request->has($key)) {
                $assets = $this->searchAssetRepository->filterByRelationalDateFields($assets, $request->$key, $value['relation'], $value['db_field']);
            }
        }


        $assets = $this->searchAssetRepository->searchAssetWithHardwareStandard($assets, $request->hardware_standard);

        if ($request->has('user')) {
            $assets = $this->searchAssetRepository->searchAssetWithUserFIelds($assets, $request->user);
        }

        if ($request->has('employee_status')) {
            $assets = $this->searchAssetRepository->searchAssetWithEmployeeStatus($assets, $request->employee_status);
        }


        if ($request->has('terminated_date_from') || $request->has('terminated_date_to')) {
            $assets = $this->searchAssetRepository->searchAssetsWithinTerminatedDates($assets, $request->terminated_date_from ?? '', $request->terminated_date_to ?? '');
        }

        return $assets;
    }

    /**
     * Get terminated user assets with pagination and optional filtering.
     *
     * @param GetAssetRequest $request The HTTP request object.
     *
     * @return TerminatedAssetCollection
     */
    public function getTerminatedUserAssets(GetAssetRequest $request)
    {
        $assets = $this->searchAssetRepository->getJoinedAssetQuery();
        $assets = $this->searchAssetRepository->getTerminatedUserAssets($assets);
        $assets = $this->filterAssets($request, $assets);

        $limit     = $this->getQueryLimit($request->limit);

        return new TerminatedAssetCollection($assets->paginate($limit));
    }
}
