<?php

declare(strict_types=1);

namespace PrettyLinks\Pro\Rest;

use PrettyLinks\Pro\Repositories\Tags as TagsRepo;
use PrettyLinks\Rest\Controllers\BaseController;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

class TagsController extends BaseController
{
    /**
     * Register the tags REST routes.
     *
     * @return void
     */
    public function register(): void
    {
        register_rest_route($this->namespace(), '/tags', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'index'],
                'permission_callback' => $this->permission(),
            ],
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [$this, 'create'],
                'permission_callback' => $this->permission(),
            ],
        ]);

        register_rest_route($this->namespace(), '/tags/(?P<id>\d+)', [
            [
                'methods'             => WP_REST_Server::EDITABLE,
                'callback'            => [$this, 'update'],
                'permission_callback' => $this->permission(),
            ],
            [
                'methods'             => WP_REST_Server::DELETABLE,
                'callback'            => [$this, 'delete'],
                'permission_callback' => $this->permission(),
            ],
        ]);
    }

    /**
     * Return all tags.
     *
     * @return WP_REST_Response
     */
    public function index(): WP_REST_Response
    {
        return new WP_REST_Response($this->repo()->all());
    }

    /**
     * Create a tag from the request body.
     *
     * @param WP_REST_Request $request Incoming REST request.
     *
     * @return WP_REST_Response
     */
    public function create(WP_REST_Request $request): WP_REST_Response
    {
        $row = $this->repo()->create((array) $request->get_json_params());
        return new WP_REST_Response($row, 201);
    }

    /**
     * Update a tag by id.
     *
     * @param WP_REST_Request $request Incoming REST request.
     *
     * @return WP_REST_Response
     */
    public function update(WP_REST_Request $request): WP_REST_Response
    {
        $id  = (int) $request['id'];
        $row = $this->repo()->update($id, (array) $request->get_json_params());
        if ($row === null) {
            return new WP_REST_Response(['error' => 'not_found'], 404);
        }
        return new WP_REST_Response($row);
    }

    /**
     * Delete a tag by id.
     *
     * @param WP_REST_Request $request Incoming REST request.
     *
     * @return WP_REST_Response
     */
    public function delete(WP_REST_Request $request): WP_REST_Response
    {
        $id = (int) $request['id'];
        return new WP_REST_Response(['success' => $this->repo()->delete($id)]);
    }

    /**
     * Resolve the tags repository from the container.
     *
     * @return TagsRepo
     */
    private function repo(): TagsRepo
    {
        return $this->container->get(TagsRepo::class);
    }
}
