<?php

namespace App\Http\Resources;

use App\Facades\Settings;
use App\Traits\FranchiseData;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Collection;
use Mtc\ContentManager\Contracts\PageModel;
use Mtc\ContentManager\Facades\Page;

class PageTreeResource extends JsonResource
{
    use FranchiseData;

    /**
     * @var LengthAwarePaginator|Collection
     */
    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)
    {
        if ($this->resource instanceof LengthAwarePaginator) {
            $this->resource->through(fn (PageModel $page) => $this->map($page));

            $data = $this->resource->toArray();
            $data['soft_deletes'] = true;
            return $data;
        }

        $grouped = $this->groupByCategory($this->resource);

        return [
            'data' => $grouped->values()->toArray(),
            'soft_deletes' => true,
        ];
    }

    /**
     * Group pages by category, creating virtual parent nodes for blog/news
     */
    private function groupByCategory(Collection $pages): Collection
    {
        $pageTypes = collect(config('pages.page_types', []));
        $pageTypeCategories = $pageTypes->pluck('value')->toArray();
        $result = collect();

        // Get regular pages (not blog/news) and map them normally
        $regularPages = $pages->filter(fn (PageModel $page) => !in_array($page->category, $pageTypeCategories, true));
        $result = $result->merge($regularPages->map(fn (PageModel $page) => $this->map($page)));

        // Group blog/news pages under virtual parent nodes
        foreach ($pageTypes as $pageType) {
            if (!Settings::get($pageType['config_key'])) {
                continue;
            }

            $categoryPages = $pages->filter(fn (PageModel $page) => $page->category === $pageType['value']);

            if ($categoryPages->isEmpty()) {
                continue;
            }

            $result->push($this->createVirtualGroupNode(
                $pageType['name'],
                $pageType['value'],
                $categoryPages
            ));
        }

        return $result;
    }

    /**
     * Create a virtual group node for categorized pages
     */
    private function createVirtualGroupNode(string $name, string $category, Collection $pages): array
    {
        return [
            'id' => 'group-' . $category,
            'title' => $name,
            'active' => true,
            'status' => 'published',
            'children' => $pages->map(fn (PageModel $page) => $this->map($page))->values()->toArray(),
            'expanded' => false,
            'menu_open' => false,
            'description' => $pages->count() . ' ' . strtolower($name) . ' articles',
            'link' => null,
            'disallow_delete' => true,
            'deleted_at' => null,
            'metaItems' => [],
            'featured' => false,
            'isVirtualGroup' => true,
        ];
    }

    /**
     * Map page entry
     */
    private function map(PageModel $page): array
    {
        return [
            'id' => $page->id,
            'title' => $page->title,
            'active' => $page->status === 'published',
            'status' => $page->status,
            'children' => $page->children->map(fn (PageModel $child) => $this->map($child)),
            'expanded' => false,
            'menu_open' => false,
            'description' => collect([
                $page->deleted_at ? 'Archived' : null,
                $page->slug,
                $page->template?->name
            ])
                ->filter()
                ->implode(' | '),
            'link' => '/manage-content/content/edit/' . $page->id,
            'disallow_delete' => Page::canRemove($page->id) !== true,
            'deleted_at' => $page->deleted_at,
            'metaItems' => [
                $page->updated_at->diffForHumans(),
            ],
            'featured' => (bool) $page->featured,
        ];
    }
}
