<?php

namespace App\Services;

use Exception;

class AdvanceSearchService
{
    /**
     * @param string $tableName
     * @param string $queryParams
     *
     * @return object
     */
    public function search(string $tableName, string $queryParams, $repository)
    {
        try {
            $decodedFilters = $this->decodeQueryParameters($queryParams);
            $filters = $this->validateQueryParameters($decodedFilters);
            return $repository->search($filters, $tableName);
        } catch (Exception $e) {
            app('log')->error("Error", ['errorMessage' => $e->getMessage()]);
            throw new Exception($e->getMessage());
        }
    }

    public function decodeQueryParameters(string $queryParams)
    {
        try {
            $decodedParams = base64_decode($queryParams);
            $filters = json_decode($decodedParams, true);
            if (!is_array($filters)) {
                throw new Exception("Invalid query parameters");
            }
            return $filters;
        } catch (Exception $e) {
            app('log')->error("Error", ['errorMessage' => $e->getMessage()]);
            throw new Exception($e->getMessage());
        }
    }

    /**
     * @param array $filters
     *
     * @return array
     */
    public function validateQueryParameters(array $filters): array
    {
        try {
            $isValid = true;
            foreach ($filters as $filter) {
                if (array_key_exists('pageInfo', $filter)) {
                    if (!array_key_exists('page', $filter['pageInfo']) || !array_key_exists('limit', $filter['pageInfo'])) {
                        $isValid = false;
                        break;
                    }
                } elseif (array_key_exists('sortInfo', $filter)) {
                    if (!array_key_exists('key', $filter['sortInfo'])) {
                        $isValid = false;
                        break;
                    }
                } elseif (array_key_exists('withRelationship', $filter)) {
                    if (!array_key_exists('name', $filter['withRelationship'])) {
                        $isValid = false;
                        break;
                    }
                } elseif (!array_key_exists('key', $filter) || !array_key_exists('condition', $filter) || !array_key_exists('value', $filter)) {
                    $isValid = false;
                    break;
                }
            }
            if (!$isValid) {
                throw new Exception("Invalid query parameters");
            }
            return $filters;
        } catch (Exception $e) {
            app('log')->error("Error", ['errorMessage' => $e->getMessage()]);
            throw new Exception($e->getMessage());
        }
    }
}
