<?php

namespace FSPoster\App\Pages\ContentIdeas\Controllers;

use Exception;
use FSPoster\App\Pages\ContentIdeas\Services\ContentIdeaService;
use FSPoster\App\Providers\Core\RestRequest;
use FSPoster\App\Providers\License\PlanFeatures;

class ContentIdeaController
{
    private ContentIdeaService $service;

    public function __construct(ContentIdeaService $service)
    {
        $this->service = $service;
    }

    public function getAll(RestRequest $request): array
    {
        $page         = $request->param('page', 1, RestRequest::TYPE_INTEGER);
        $perPage      = $request->param('per_page', 10, RestRequest::TYPE_INTEGER);
        $search       = $request->param('search', '', RestRequest::TYPE_STRING);
        $starred      = $request->param('starred', '', RestRequest::TYPE_STRING, ['starred', 'unstarred']);
        $createdByIds = $request->param('created_by_ids', [], RestRequest::TYPE_ARRAY);

        $page    = $page > 0 ? $page : 1;
        $perPage = in_array($perPage, [10, 12]) ? $perPage : 10;

        return $this->service->getAll([
            'page'           => $page,
            'per_page'       => $perPage,
            'search'         => $search,
            'starred'        => $starred,
            'created_by_ids' => $createdByIds,
        ]);
    }

    /**
     * @throws Exception
     */
    public function get(RestRequest $request): array
    {
        $id = $request->param('id', 0, RestRequest::TYPE_INTEGER);

        return $this->service->get($id);
    }

    /**
     * @throws Exception
     */
    public function save(RestRequest $request): array
    {
        $this->ensureWriteAccess();

        $id           = $request->param('id', null, RestRequest::TYPE_INTEGER);
        $isStarred    = $request->param('is_starred', null, RestRequest::TYPE_BOOL);
        $title        = $request->param('title', null, RestRequest::TYPE_STRING);
        $mediaIds     = $request->param('media_ids', null, RestRequest::TYPE_ARRAY);
        $link         = $request->param('link', null, RestRequest::TYPE_STRING);
        $firstComment = $request->param('first_comment', null, RestRequest::TYPE_STRING);

        if (!empty($id)) {
            if ($isStarred !== null && $title === null) {
                return $this->service->save([
                    'id'        => $id,
                    'is_starred' => $isStarred,
                ]);
            }

            $title   = $request->require('title', RestRequest::TYPE_STRING, fsp__('Title is required'));
            $content = $request->require('content', RestRequest::TYPE_STRING, fsp__('Content is required'));

            return $this->service->save([
                'id'            => $id,
                'title'         => $title,
                'content'       => $content,
                'media_ids'     => $mediaIds,
                'link'          => $link,
                'first_comment' => $firstComment,
                'is_starred'    => $isStarred,
            ]);
        }

        $title   = $request->require('title', RestRequest::TYPE_STRING, fsp__('Title is required'));
        $content = $request->require('content', RestRequest::TYPE_STRING, fsp__('Content is required'));

        return $this->service->save([
            'title'         => $title,
            'content'       => $content,
            'media_ids'     => $mediaIds,
            'link'          => $link,
            'first_comment' => $firstComment,
            'is_starred'    => $isStarred,
        ]);
    }

    public function delete(RestRequest $request): array
    {
        $this->ensureWriteAccess();

        $all     = $request->param('include_all', false, RestRequest::TYPE_BOOL);
        $exclude = $request->param('exclude_ids', [], RestRequest::TYPE_ARRAY);
        $include = $request->param('include_ids', [], RestRequest::TYPE_ARRAY);

        return $this->service->delete([
            'all'     => $all,
            'exclude' => $exclude,
            'include' => $include,
        ]);
    }

    /**
     * @throws Exception
     */
    private function ensureWriteAccess(): void
    {
        if (! PlanFeatures::isFeatureAllowed('content_ideas')) {
            throw new Exception(fsp__('Content Ideas is not available in your current plan'));
        }
    }
}
