<?php
namespace Misuzu\Emoticons;

use RuntimeException;
use Index\XArray;
use Index\Http\{HttpRequest,HttpResponseBuilder};
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
use Index\Http\Routing\AccessControl\AccessControl;
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
use Misuzu\FieldTransformer;

final class EmotesApiRoutes implements RouteHandler {
    use RouteHandlerCommon;

    public function __construct(
        private EmotesContext $emotesCtx
    ) {}

    /** @return FieldTransformer<EmoteInfo> */
    private function createEmoteTransformer(): FieldTransformer {
        return new FieldTransformer([
            'id' => [
                'transform' => fn($emote) => $emote->id,
            ],
            'order' => [
                'transform' => fn($emote) => $emote->order,
            ],
            'url' => [
                'default' => true,
                'transform' => fn($emote) => $emote->url,
            ],
            'strings' => [
                'default' => true,
                'transform' => fn($emote) => XArray::select(
                    $this->emotesCtx->emotes->getEmoteStrings($emote),
                    fn($string) => $string->string
                ),
            ],
            'min_rank' => [
                'default' => true,
                'transform' => fn($emote) => $emote->minRank,
                'include' => fn($value) => $value !== 0,
            ],
        ]);
    }

    /** @return int|mixed[] */
    #[AccessControl]
    #[ExactRoute('GET', '/api/v1/emotes')]
    public function getEmotes(HttpRequest $request): array|int {
        $transformer = $this->createEmoteTransformer();
        if(!$transformer->filter($request))
            return 400;

        return XArray::select(
            $this->emotesCtx->emotes->getEmotes(orderBy: 'order'),
            fn($emote) => $transformer->convert($emote),
        );
    }

    /** @return int|mixed[] */
    #[AccessControl]
    #[PatternRoute('GET', '/api/v1/emotes/([0-9]+)')]
    public function getEmote(HttpRequest $request, string $id): array|int {
        if(empty($id))
            return 404;

        $transformer = $this->createEmoteTransformer();
        if(!$transformer->filter($request))
            return 400;

        try {
            $emote = $this->emotesCtx->emotes->getEmote($id);
        } catch(RuntimeException $ex) {
            return 404;
        }

        return $transformer->convert($emote);
    }

    /** @return FieldTransformer<EmoteStringInfo> */
    private function createEmoteStringTransformer(): FieldTransformer {
        return new FieldTransformer([
            'order' => [
                'transform' => fn($string) => $string->order,
            ],
            'string' => [
                'default' => true,
                'transform' => fn($string) => $string->string,
            ],
        ]);
    }

    /** @return int|mixed[] */
    #[AccessControl]
    #[PatternRoute('GET', '/api/v1/emotes/([0-9]+)/strings')]
    public function getEmoteStrings(HttpRequest $request, string $id): array|int {
        if(empty($id))
            return 404;

        $transformer = $this->createEmoteStringTransformer();
        if(!$transformer->filter($request))
            return 400;

        try {
            $emote = $this->emotesCtx->emotes->getEmote($id);
        } catch(RuntimeException $ex) {
            return 404;
        }

        return XArray::select(
            $this->emotesCtx->emotes->getEmoteStrings($emote),
            fn($emote) => $transformer->convert($emote),
        );
    }
}