<?php

declare(strict_types=1);

namespace App\Base;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\Paginator;
use Symfony\Component\HttpFoundation\Response;

class AbstractResponse
{
    const MessageOk = 'OK';

    /**
     * @return array<string, mixed>
     */
    public static function getData(Model $Item): array
    {
        return $Item->toArray();
    }

    /**
     * @param  Model[]  $Itemzz
     * @return array<int, array<string, mixed>>
     */
    public static function getDatazz(array $Itemzz): array
    {
        return array_map(function ($Item) {
            return static::getData($Item);
        }, $Itemzz);
    }

    /**
     * @template T of Model
     *
     * @param  array<string, mixed>|null  $Item
     * @param  array<int, array<string, mixed>>  $Itemzz
     * @param  ?Paginator<T>  $Page
     * @return array<string, mixed>
     */
    public static function makeData(
        int $Code = 200,
        mixed $Data = null,
        ?array $Item = null,
        array $Itemzz = [],
        string $Message = '',
        ?Paginator $Page = null,
    ): array {
        return compact('Code', 'Data', 'Item', 'Itemzz', 'Message', 'Page');
    }

    public static function sendData(string $Message, mixed $Data, int $Code): JsonResponse
    {
        return new JsonResponse(
            static::makeData(
                $Code,
                $Data,
                null,
                [],
                $Message,
            ),
            $Code,
        );
    }

    public static function sendModelItem(Model $Item, string $Message = self::MessageOk, int $Code = Response::HTTP_OK): JsonResponse
    {
        return static::sendItem(static::getData($Item), $Message, $Code);
    }

    /**
     * @param  array<string, mixed>  $Item
     */
    public static function sendItem(array $Item, string $Message = self::MessageOk, int $Code = Response::HTTP_OK): JsonResponse
    {
        return new JsonResponse(
            static::makeData(
                $Code,
                null,
                $Item,
                [],
                $Message,
            ),
            $Code,
        );
    }

    /**
     * @param  Model[]  $Itemzz
     */
    public static function sendModelItemzz(array $Itemzz, string $Message = self::MessageOk, int $Code = Response::HTTP_OK): JsonResponse
    {
        return static::sendItemzz(static::getDatazz($Itemzz), $Message, $Code);
    }

    /**
     * @param  array<int, array<string, mixed>>  $Itemzz
     */
    public static function sendItemzz(array $Itemzz, string $Message = self::MessageOk, int $Code = Response::HTTP_OK): JsonResponse
    {
        return new JsonResponse(
            static::makeData(
                $Code,
                null,
                null,
                $Itemzz,
                $Message,
            ),
            $Code,
        );
    }

    public static function sendOK(mixed $Data = null): JsonResponse
    {
        return static::sendData(self::MessageOk, $Data, Response::HTTP_OK);
    }

    /**
     * @template T of Model
     *
     * @param  Paginator<T>  $Paginator
     */
    public static function sendPage(Paginator $Paginator, string $Message = self::MessageOk, int $Code = Response::HTTP_OK): JsonResponse
    {
        return new JsonResponse(
            static::makeData(
                $Code,
                null,
                null,
                [],
                $Message,
                $Paginator,
            ),
            $Code,
        );
    }
}
