<?php

namespace App\Http\Controllers\Backend;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Inertia\Inertia;

use App\Http\Requests\Backend\PageBuilder\IndexRequest;
use App\Http\Requests\Backend\PageBuilder\CreateRequest;
use App\Http\Requests\Backend\PageBuilder\EditRequest;
use App\Http\Requests\Backend\PageBuilder\DeleteRequest;
use App\Http\Requests\Backend\PageBuilder\PreviewRequest;
use App\Http\Requests\Backend\PageBuilder\SetActiveRequest;

use App\Models\PageRevision;
use App\Models\ImageNode;
use App\Models\Page;

use App\Helpers\PageBlocksHelper;

class PageBuilder extends Controller
{
    public function index(IndexRequest $request) {
        $pages = Page::with(['author', 'activeRevision'])->withCount('revisions')->get();

        return Inertia::render('Backend/PageBuilder/Index', [
            'builtPages' => $pages->map(function ($page) {
                return [
                    'id'        => $page->id,
                    'uuid'      => $page->uuid,
                    'title'     => $page->title,
                    'slug'      => $page->slug,
                    'content'   => $page->content,
                    'revisions_count' => $page->revisions_count,
                    'author' => [
                        'id' => $page->author->id,
                        'name' => $page->author->name,
                    ],
                    'activeRevision' => $page->activeRevision ? [
                        'uuid' => $page->activeRevision->uuid,
                        'version' => $page->activeRevision->version,
                    ] : null
                ];
            }),
        ]);
    }

    public function createLandingPage(CreateRequest $request) {
        $imagesNodes = ImageNode::all();
        return Inertia::render('Backend/PageBuilder/Create', [
            'images'    => $imagesNodes
        ]);
    }

    public function storeLandingPage(CreateRequest $request) {
        $data = $request->validated();

        // Initiate slug duplication detection
        $baseSlug = Str::slug($data['title']);
        $slug = $baseSlug;
        $suffix = 1;

        while (Page::where('slug', $slug)->exists()) {
            $slug = $baseSlug . '-' . $suffix++;
        }

        // If this page should be the main page, unset main on others
        if ($data['mainpage']) {
            Page::where('main', true)->update(['main' => false]);
        }

        $page = Page::create([
            'uuid'         => Str::uuid(),
            'user_id'      => Auth::id(),
            'title'        => $data['title'],
            'slug'         => $slug,
            'content'      => $data['content'],
            'is_published' => $data['publish'],
            'main'         => $data['mainpage'],
            'linked'       => $data['linked'],
            'linkorder'    => $data['linkorder'],
            'visibility'   => $data['visibility'],
        ]);

        $rev = PageRevision::create([
            'page_id'   => $page->id,
            'user_id'   => Auth::id(),
            'title'     => $page->title,
            'slug'      => $page->slug,
            'content'   => $page->content,
            'label'     => $page->is_published ? 'published' : 'manual-save',
            'active'    => true
        ]);

        return to_route('page-builder.builder.edit', ['pageVersion' => $rev->uuid]);
    }

    public function deleteLandingPage(DeleteRequest $request) {
        $page = Page::findOrFail($request->id);

        // Check if the user is the owner of the page (removed permission checking for standalone pagebuilder code)
        if (Auth::user()->id != $page->user_id) {
            return to_route('page-builder.index')
                ->with('error', "Du er ikke forfatteren av denne siden og kan derfor ikke slette den.");
        }

        $page->delete();

        return to_route('page-builder.index')->with('warning', 'Siden ble slettet.');
    }

    public function editLandingPage(EditRequest $request, PageRevision $pageVersion) {
        $revision = $pageVersion->load(['page.revisions.editor', 'editor']);
        $images = ImageNode::all();

        $pageRevisions = $revision->page->revisions->map(function ($rev) {
            return [
                'id'        => $rev->id,
                'title'     => $rev->title,
                'uuid'      => $rev->uuid,
                'version'   => $rev->version,
                'active'    => $rev->active,
                'created_at'=> $rev->created_at,
                'updated_at'=> $rev->updated_at,
                'author'    => [
                    'name'  => $rev->editor->name,
                    'email' => $rev->editor->email
                ]
            ];
        });

        return Inertia::render('Backend/PageBuilder/Edit', [
            'revision' => [
                'id'        => $revision->id,
                'uuid'      => $revision->uuid,
                'version'   => $revision->version,
                'title'     => $revision->title,
                'slug'      => $revision->slug,
                'label'     => $revision->label,
                'active'    => $revision->active,
                'content'   => $revision->content,
                'page' => [
                    'id'          => $revision->page->id,
                    'uuid'        => $revision->page->uuid,
                    'is_published'=> $revision->page->is_published,
                    'main'        => $revision->page->main,
                    'linked'      => $revision->page->linked,
                    'linkorder'   => $revision->page->linkorder,
                    'visibility'  => $revision->page->visibility,
                ]
            ],
            'images' => $images,
            'revisions' => $pageRevisions
        ]);
    }

    public function patchLandingPage(EditRequest $request) {
        $data = $request->validated();

        // Load the revision by uuid
        $revision = PageRevision::where('uuid', $request->input('revision_uuid'))
            ->with('page')
            ->firstOrFail();

        // Check if the user is the owner of the current revision (removed permission checking for standalone pagebuilder code
        if (Auth::user()->id != $revision->user_id) {
            return to_route('page-builder.builder.edit', ['pageVersion' => $revision->uuid])
                ->with('info', "Du er ikke forfatteren av denne revisjonen og kan derfor ikke gjøre endringer til den. Hvis du ønsker å gjøre endringer, lagre denne revisjonen som en ny versjon.");
        }

        // If this page should be the main page, unset main on others
        if ($data['mainpage']) {
            Page::where('main', true)->where('id', '!=', $revision->page_id)->update(['main' => false]);
        }

        // Check if user can publish (removed permission checking for standalone pagebuilder code
        $canPublish = true;
        $publish = $canPublish ? $data['publish'] : false;

        if ($revision->active) {
            // Initiate slug duplication detection
            $baseSlug = Str::slug($data['title']);
            $slug = $baseSlug;
            $suffix = 1;
    
            // ONly update slug if it has changed
            if ($baseSlug !== $revision->page->slug) {
                while (Page::where('slug', $slug)->where('id', '!=', $revision->page_id)->exists()) {
                    $slug = $baseSlug . '-' . $suffix++;
                }
            } else {
                $slug = $revision->page->slug;
            }

            // Update the base page model if the current revision is set to active
            $revision->page->update([
                'title'        => $data['title'],
                'slug'         => $slug,
                'content'      => $data['content'],
                'is_published' => $publish,
                'main'         => $data['mainpage'],
                'linked'       => $data['linked'],
                'linkorder'    => $data['linkorder'],
                'visibility'   => $data['visibility'],
            ]);
        }

        // Update the current revision directly
        $revision->update([
            'title'    => $data['title'],
            'slug'     => Str::slug($data['title']),
            'content'  => $data['content'],
            'label'    => $publish ? 'published' : 'manual-save',
        ]);

        if ($request->has('autosave') && $request->input('autosave')) {
            return to_route('page-builder.builder.edit', ['pageVersion' => $revision->uuid])
                ->with('info', 'Endringer lagret automatisk.');
        }

        return to_route('page-builder.builder.edit', ['pageVersion' => $revision->uuid])
            ->with('success', 'Endringer ble lagret i nåværende revisjon.');
    }

    public function saveAsLandingPage(CreateRequest $request) {
        $data = $request->validated();
        $page = Page::findOrFail($request->page_id);

        $revision = PageRevision::create([
            'page_id'   => $page->id,
            'user_id'   => Auth::id(),
            'title'     => $data['title'],
            'slug'      => Str::slug($data['title']),
            'content'   => $data['content'],
            'label'     => 'manual-save',
            'active'    => false
        ]);

        return to_route('page-builder.builder.edit', ['pageVersion' => $revision->uuid])
            ->with('success', "Ny versjon (v. {$revision->version}) opprettet.");
    }

    public function setLandingPageRevisionActive(SetActiveRequest $request) {
        $revision = PageRevision::where('uuid', $request->input('revision_uuid'))->firstOrFail();

        $data = $request->validated();
        
        $page = $revision->page;

        PageRevision::where('active', true)->where('page_id', '=', $page->id)->update(['active' => false]);
        $revision->active = true;
        $revision->save();

        // Initiate slug duplication detection
        $baseSlug = Str::slug($data['title']);
        $slug = $baseSlug;
        $suffix = 1;

        while (Page::where('slug', $slug)->exists()) {
            $slug = $baseSlug . '-' . $suffix++;
        }

        $page->title = $data['title'];
        $page->slug = $slug;
        $page->content = $data['content'];
        $page->is_published = false;

        $page->save;

        return to_route('page-builder.builder.edit', ['pageVersion' => $revision->uuid])
            ->with('success', "Versjon {$revision->version} satt som innhold til siden.");
    }

    public function preview(PreviewRequest $request, PageRevision $pageVersion) {
        $revision = $pageVersion->load(['page', 'editor']);
        $images = ImageNode::all();

        $neededFetchers = collect();

        $blocks = json_decode($revision->content, true);

        foreach ($blocks as $block) {
            if (!empty($block['needs'])) {
                $neededFetchers = $neededFetchers->merge($block['needs']);
            }
        }

        $neededFetchers = $neededFetchers->unique();

        $blockData = [];

        foreach ($neededFetchers as $fetcher) {
            if (method_exists(PageBlocksHelper::class, $fetcher)) {
                $blockData[$fetcher] = PageBlocksHelper::$fetcher();
            }
        }

        return Inertia::render('Backend/PageBuilder/Preview', [
            'revision' => [
                'id'        => $revision->id,
                'uuid'      => $revision->uuid,
                'version'   => $revision->version,
                'title'     => $revision->title,
                'slug'      => $revision->slug,
                'label'     => $revision->label,
                'active'    => $revision->active,
                'content'   => json_decode($revision->content, true),
                'page' => [
                    'id'          => $revision->page->id,
                    'uuid'        => $revision->page->uuid,
                    'is_published'=> $revision->page->is_published,
                    'main'        => $revision->page->main,
                    'visibility'  => $revision->page->visibility,
                ]
            ],
            'images'    => $images,
            'blockData' => $blockData,
            'menuLinks' => PageBlocksHelper::mainMenuLinks()
        ]);
    }
}