<?php

namespace App\Providers;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\ServiceProvider;
use Spatie\Translatable\HasTranslations;

class ApiServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap services.
     */
    public function boot(): void
    {
        /**
         * REST response (JSON syntactic-sugar)
         *
         * @param  mixed  $data
         * @param  int  $status_code
         * @param  string  $message
         * @return \Illuminate\Http\JsonResponse
         */
        Response::macro('rest', function (mixed $data = [], int $code = 200, string $message = 'success'): JsonResponse {
            return response()->json(['message' => $message, 'data' => $data], $code);
        });

        /**
         * REST response (JSON syntactic-sugar)
         *
         * @param  mixed  $data
         * @param  int  $status_code
         * @param  string  $message
         * @return \Illuminate\Http\JsonResponse
         */
        Response::macro('rest_paginate', function (mixed $data, int $code = 200, string $message = 'success'): JsonResponse {
            return response()->json([
                'message' => $message,
                'data' => $data->items(),
                'pagination' => [
                    'page' => $data->currentPage(),
                    'perPage' => $data->perPage(),
                    'count' => $data->count(),
                    'first_page_url' => $data->url(1),
                    'next_page_url' => $data->nextPageUrl(),
                    'prev_page_url' => $data->previousPageUrl(),
                ],
            ], $code);
        });

        /**
         * Order by translation for spatie/laravel-translatable
         *
         * @param  string  $field
         * @param  string  $order
         * @param  string  $locale
         * @return \Illuminate\Database\Eloquent\Builder
         */
        Builder::macro('orderByTranslation', function (string $field, string $order = 'asc', ?string $locale = null) {
            if (
                in_array(HasTranslations::class, class_uses($this->model))
                && in_array($field, $this->model->translatable)
                && config('database.default') === 'pgsql'
            ) {
                $locale = $locale ?? app()->getLocale();
                $this->query->orderByRaw("$field->>'$locale' $order");
            } else {
                $this->query->orderBy($field, $order);
            }

            return $this;
        });
    }
}
