<?php

namespace App\Http\Resources;

use App\Facades\Settings;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Mtc\ContentManager\Traits\MapContentTrait;
use Mtc\MercuryDataModels\ContentElement;
use Mtc\MercuryDataModels\GlobalContent;

class VersionViewResource extends JsonResource
{
    use MapContentTrait;

    public static $wrap = '';

    /**
     * @var LengthAwarePaginator
     */
    public $resource;

    /**
     * Transform the resource into an array.
     *
     * @param \Illuminate\Http\Request $request
     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
     */
    #[\Override]
    public function toArray($request)
    {
        $this->resource->load([
            'page.template',
            'allContent.mediaUses.media',
            'allContent.contentElement.fields',
            'allContent.globalContent.contentElement.fields',
        ]);

        $resource = $this->resource->toArray();

        $resource['author_name'] = $this->resource->author?->name;

        $resource['user_can_save'] = $this->userCanSaveResource();
        $resource['user_can_publish'] = $this->userCanPublishResource();
        $resource['editableContentStructure'] = $this->canEditContent();

        unset($resource['page']['text']);
        $resource['pageTitle'] = 'Version ' . $resource['id'] . ' | ' . $this->resource->page->title;

        $resource['content'] = $this->organiseContentInTree($this->resource->allContent)
            ->map(fn ($content) => $this->mapContent($content));
        $blockResource = config('pages.content_element_block_resource');
        $elements = ContentElement::query()
            ->with('fields.childElement.fields.childElement.fields.childElement.fields')
            ->where('is_enabled', 1)
            ->where('drag_and_drop', 1)
            ->paginate(10);
        $resource['content_review_enabled'] = Settings::get('pages-versioning-content-review-mode');
        $resource['url'] = $this->resource->url();
        $page = $resource['page'];
        unset($resource['page']);
        return [
            'page' => $page,
            'version' => $resource,
            'global_content' => new $blockResource(GlobalContent::query()->paginate(10)),
            'elements' => new $blockResource($elements),
        ];
    }

    private function userCanSaveResource(): bool
    {
        return empty($this->resource->author_id) || Auth::id() === $this->resource->author_id;
    }

    private function userCanPublishResource(): bool
    {
        return Auth::user()->hasPermissionTo('publish-content');
        // TODO: Further implementation of per-page restrictions on editor rights
    }

    private function organiseContentInTree(Collection $entries, ?int $parent_id = null): Collection
    {
        $branch = collect();

        $entries->filter(fn ($entry) => $entry->parent_id === $parent_id)
            ->each(function ($entry) use ($branch, $entries) {
                $children = $this->organiseContentInTree($entries, $entry->id);
                if ($children->isNotEmpty()) {
                    $entry['children'] = $children;
                } else {
                    $entry['children'] = collect();
                }
                $branch[] = $entry;
            });

        return $branch;
    }

    private function canEditContent(): bool
    {
        // No template or template is specified as flexible
        return is_null($this->resource->page->template_id)
            || ($this->resource->page->template?->meta && $this->resource->page->template?->meta['flexible'] ?? false);
    }
}
